java——动态规划03

01背包问题:

背包问题算是动态规划中,最经典的题目了,分为01背包,和完全背包问题,不过两者有比较密切的关系,01背包搞明白了,完全背包自然迎刃而解,下面和大家共同探索一道01背包最大价值问题。

题目描述:

有一下商品,价值和重量如表所示,问给定一个重量为4的背包,怎样装东西,能使获得的价值最大。

商品 价值 重量
手机 1500 1
吹风机 800 2
平板 2000 2

解决此问题时,最好借用画表的方法,由于本人也是刚开始学,所以把想法说明下。

咱们先建立一个二维数组dp[i][j],w[i]表示第i件商品的重量,背包重量W,用来表示前i件商品中获得的最大价值。

刚开始一件商品也不选,则背包内价值为0,也就是二维数组的第一行全0(dp[0][j]),同样的假设背包重量为0,则一件商品也装不进去,所以第一列全为0(dp[i][0]),初始化第一行和第一列后,开始依次往背包放东西。

第一次只允许第一件商品放入,则在第一行所有重量满足的情况下,都将获得第一件商品的价值。

接下来允许放入两件商品,同理在重量满足的情况下,需考虑是否将第二件商品放入背包,这就需要比较,前i件商品的价值,与加上背包的价值,哪个价值更大。由此可以有以下代码:

public class test12 {
	public static void main(String[] args) {
		int[]w={1,2,2};//物品的重量
		int[]val={1500,800,2000};//物品的价值
		int m=4;//背包的重量
		int n=val.length;
		int[][]v=new int[n+1][m+1];//二维数组,用来表示前i件商品的最大价值
		int[][]path=new int[n+1][m+1];//用来记录哪个商品被放入背包
		for(int i=1;i<v.length;i++){//这里从i=1,j=1开始遍历,和商品对应
			for(int j=1;j<v[0].length;j++){
				if(w[i-1]>j){//当商品重量大于背包重量
					v[i][j]=v[i-1][j];
				}
				else{//当背包重量大于商品重量时
					if(v[i-1][j]<val[i-1]+v[i-1][j-w[i-1]]){//判断在剩下的重量 选择放还是不放,要比较价值的大小,不放时和放时
						v[i][j]=val[i-1]+v[i-1][j-w[i-1]];
						path[i][j]=1;//选择了放,将放入的进行标记
					}
					else{//没有放进去
						v[i][j]=v[i-1][j];
					}
				}
			}
		}
		System.out.println(v[n][m]);//打印最大价值

		for(int i=0;i<v.length;i++){//输出价值表
			for(int j=0;j<v[0].length;j++){
				System.out.print(v[i][j]+" ");
			}
			System.out.println();
		}
		System.out.println("--------------------");
		int s=path.length-1;
		int q=path[0].length-1;
		while(s>0&&q>0){//判断输出选择的商品,这里从后往前遍历,否则有冗余情况
			if(path[s][q]==1){
				System.out.println("把第"+s+"个装入背包内");
				q-=w[s-1];//将最后放进去后,重量将发生变化,求剩余重量
			}
			s--;//下一个商品
		}
	}
}

结果如下:

猜你喜欢

转载自blog.csdn.net/qq_52705208/article/details/123854095
今日推荐