Leetcode 0/1背包问题

Leetcode 0/1背包问题


什么是背包问题?比如有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?(0/1背包问题就是这n个物品中某一个物品选还是不选,分别表示1和0)
**题目描述:**比如有n个物品,它们有各自的体积w和价值v,现有给定容量的背包bagV,如何让背包里装入的物品具有最大的价值总和?
解题步骤:
在解决问题之前,为描述方便,首先定义一些变量:Vi表示第 i 个物品的价值,Wi表示第 i 个物品的体积,定义V(i,j):当前背包容量 j,前 i 个物品最佳组合对应的价值,同时背包问题抽象化(X1,X2,…,Xn,其中 Xi 取0或1,表示第 i 个物品选或不选)。
1、建立模型,即求max(V1X1+V2X2+…+VnXn);
2、寻找约束条件,W1X1+W2X2+…+WnXn<capacity;
3、寻找递推关系式,面对当前商品有两种可能性:
包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);
还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个,即V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}。
其中V(i-1,j)表示不装,V(i-1,j-w(i))+v(i) 表示装了第i个商品,背包容量减少w(i),但价值增加了v(i);
4、填表,首先初始化边界条件,V(0,j)=V(i,0)=0;V[i,v]是说从前i个物品中挑出物品,将他们放入体积为v的背包可以获得的最大价值。V[0,1…n]. 可以看做是从前0个物品中挑选,放入体积分别为0,1,…,n的背包。f[0,1…n]可以看做是最简化的01背包问题了。
然后一行一行的填表:
如,i=1,j=1,w(1)=2,v(1)=3,有j<w(1),故V(1,1)=V(1-1,1)=0;
又如i=1,j=2,w(1)=2,v(1)=3,有j=w(1),故V(1,2)=max{
V(1-1,2),V(1-1,2-w(1))+v(1) }=max{0,0+3}=3;
5、输出,表格填完,最优解即V(number,capacity)=V(4,8)=10。
代码:

public class test1 {
	public static void main(String[] args) {
		test1 t1 = new test1();
		int[] w = { 0 , 2 , 3 , 4 , 5 };			//商品的体积2、3、4、5
		int[] v = { 0 , 3 , 4 , 5 , 6 };			//商品的价值3、4、5、6
		int bagV = 8;					        //背包大小
		System.out.println(t1.knapsack(w, v, bagV));

	}
	public int knapsack(int[] w,int[] v,int bagV) {
		int[][] dp = new int[w.length][bagV+1];	//动态规划表,其中i表示物品,j表示剩余的容积
		for (int i = 1; i < w.length; i++) {
			for (int j = 1; j <= bagV; j++) {
				//如果待添加的元素体积大于背包剩余体积,则取剩余体积为上一个体积
				if(j < w[i]) {
					dp[i][j] = dp[i-1][j];
				}
				//如果不大于剩余体积,则取待添加物品 加入或不加入背包后的最大值
				else {
					dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-w[i]]+v[i]);
				}
			}
		}
		return dp[w.length-1][bagV];
	}
}
发布了28 篇原创文章 · 获赞 0 · 访问量 261

猜你喜欢

转载自blog.csdn.net/zy450271923/article/details/105300515