ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【蓝桥算法】【背包问题】0-1背包与完全背包

2022-02-03 12:59:58  阅读:163  来源: 互联网

标签:背包 weight int 重量 value 蓝桥 算法 物品


背包问题:

给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高

0-1 背包:

每样物品最多只能选择一次
b站这个视频讲的很详细

思路:设value[i]与weight[i]分别表示第i个物品的价值与重量,C为背包的总重量。令v[i][j]表示在前i个物品中能够装入容量为j的背包的最大价值。

当商品重量大于背包重量时,总价值即为i物品之前的总价值。
weight[i]>j时;v[i][j]=v[i-1][j]
当商品重量小于等于背包重量,背包新的总价值取下面两者最大值:
1,不取i物品的最大总价值;
2,取了i物品,i物品的价值加上,在剩余容量为(j-weight(i))中的最大价值。

v[i][j]=Math.max(v[i-1][j],value[i]+v[i-1][j-weight[i]])
//总代码:
public class Main {
    
	
	public static void main(String[] args) {
		
		int[] weight= {1,2,3,4,5};//物品的重量
		int[] value= {3,4,6,8,10};//物品的价值
		int capacity=10;//背包重量
		int n=weight.length;//物品的种类数
		f(weight,value,n,capacity);
		
		
		
	}
	public static void f(int[] weight,int[] value,int n,int capacity) {
		int[][] v=new int[n+1][capacity+1];
		//第一行与第一列不会用到,用零填充方便理解
		//v[0][j],v[i][0]不处理默认为零
        //因此v[i][j]是从1 开始算的,而weight[]与value[]是从0开始,故设计weight[]与value[]的部分需要[i-1]
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=capacity;j++) {
				if(weight[i-1]>j)//当商品重量大于背包重量时,总价值即为i物品之前的总价值。
					v[i][j]=v[i-1][j];
				else {
					//当商品重量小于等于背包重量,背包新的总价值取下面两者最大值:
					//1,不取i物品的最大总价值;
					//2,取了i物品,i物品的价值加上,在剩余容量为(j-weight(i))中的最大价值。
					v[i][j]=Math.max(v[i-1][j],value[i-1]+v[i-1][j-weight[i-1]]);
				}
			}
			
		}
		for(int i=0;i<=n;i++) {
			for(int j=0;j<=capacity;j++) {
				System.out.print(v[i][j]+ " ");
			}
			System.out.println();
		}
		
	}
}

//进一步完善
public class Main {
   
   
   public static void main(String[] args) {
   	
   	int[] weight= {1,2,3,4,5};//物品的重量
   	int[] value= {3,4,6,8,10};//物品的价值
   	int capacity=10;//背包重量
   	int n=weight.length;//物品的种类数
   	f(weight,value,n,capacity);
   	
   	
   	
   }
   public static void f(int[] weight,int[] value,int n,int capacity) {
   	int[][] v=new int[n+1][capacity+1];
   	int[][] path=new int[n+1][capacity+1];
   	//第一行与第一列不会用到,用零填充方便理解
   	//v[0][j],v[i][0]不处理默认为零
   	//因此v[i][j]是从1 开始算的,而weight[]与value[]是从0开始,故设计weight[]与value[]的部分需要[i-1]
   	for(int i=1;i<=n;i++) {
   		for(int j=1;j<=capacity;j++) {
   			if(weight[i-1]>j)//当商品重量大于背包重量时,总价值即为i物品之前的总价值。
   				v[i][j]=v[i-1][j];
   			else {
   				//当商品重量小于等于背包重量,背包新的总价值取下面两者最大值:
   				//1,不取i物品的最大总价值;
   				//2,取了i物品,i物品的价值加上,在剩余容量为(j-weight(i))中的最大价值。
   				
   				//v[i][j]=Math.max(v[i-1][j],value[i-1]+v[i-1][j-weight[i-1]]);
   				if(v[i-1][j]<value[i-1]+v[i-1][j-weight[i-1]])
   				{
   					v[i][j]=value[i-1]+v[i-1][j-weight[i-1]];//当进行交换时
   					path[i][j]++;//路径变为1
   				}
   				else {
   					v[i][j]=v[i-1][j];
   				}
   			}
   		}
   		
   	}
   	for(int i=0;i<=n;i++) {
   		for(int j=0;j<=capacity;j++) {
   			System.out.print(v[i][j]+ " ");
   		}
   		System.out.println();
   	}
   	for(int i=0;i<=n;i++) {//输出路径矩阵
   		for(int j=0;j<=capacity;j++) {
   			System.out.print(path[i][j]+ " ");
   		}
   		System.out.println();
   	}
   	int i=n,j=capacity;
   	while(i>0&&j>0) {//利用路径矩阵输出选取的id,从后往前看
   		if(path[i][j]==1)
   		{
   			j=j-weight[i-1];//为1就看剩余容量。
   			System.out.println(i);
   		}
   		i--;
   	}
   	
   }

   
}

完全背包:

可以自己解决自己的问题
当选择拿i物品后,继续与value[i-1]+v[i][j-weight[i-1]]做比较而不是value[i-1]+v[i-1][j-weight[i-1]]

//需要改这个地方,其他一样
if(v[i-1][j]<value[i-1]+v[i][j-weight[i-1]])
   				{
   					v[i][j]=value[i-1]+v[i][j-weight[i-1]];//当进行交换时
   					path[i][j]++;//路径变为1
   				}

标签:背包,weight,int,重量,value,蓝桥,算法,物品
来源: https://blog.csdn.net/m0_54105644/article/details/122775221

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有