简介
给定两组数组w[n]和value[n],分别表示n个物品的和价值 。根据要求给出装满容积为target的背包。target即为限制条件,value在不给的情况下,比如分硬币问题中,值均为1.
背包种类
1. 0/1背包
0/1的含义是一个物品只有装入和不装入两种可能,即每种物品数量为1。问最多能装多少,即体积之和不大于target,求最大价值。
//数组初始化为0,表示在不装物品情况下不大于溶剂0-target的价值都是0.
int[] dp = new int[target+1];
for(int i = 0; i < nums[i]; ++i){
for(int j = target; j>= w[j]; --j){
dp[j] = max(dp[j], dp[j-w[j]] + v[j]);
}
}
2. 完全背包
每种物品都有无数个,这时在内层循环时不再从大往小循环,而是由小到大循环,这样可以让每种物品都放不止一次。
int[] dp = new int[target+1];
for(int i = 0; i < nums[i]; ++i){
for(int j = w[j]; j<=target; ++j){
dp[j] = max(dp[j], dp[j-w[j]] + v[j]);
}
}
3. 多重背包
有多种限制因素,除了体积外,可能还有质量m[n]等因素.
设体积w的限制是tw, 质量m的限制因素时tm。
int[][] dp = new int[tw+1][tm+1];
for(int i = 0; i < nums[i]; ++i){
for(int j = tw; j>= w[j]; --j){
for(int k = tm; k>=m[k]; --k)
dp[j] = max(dp[j][k], dp[j-w[j]][k-m[j] + v[j]);
}
}
限制类型
1. 不超过容积
不超过即是上面的解决方法,求最大用max。
这个没办法求最小,因为最小就是直接不装了呗。
2. 恰好装满
恰好即要求刚刚满足target要求。
存在否
求是否能满足用bool类型的dp数组,dp[j] = dp[j] || dp[j-w[i]]
, 记住需要初始化dp[0] = true
。
416. Partition Equal Subset Sum
最多多少个
dp[j] = dp[j] + dp[j-w[i]]
,同样需要初始化dp[0] = 1
。
494. Target Sum
最少多少个
求最少需要进行条件判断。
322. Coin Change
顺序问题
当不需要考虑物品装入顺序时,外层循环用物品,内层循环用背包限制;
当需要考虑物品装入顺序时,内外层相反, 即内层循环用物品,外层循环用背包限制。
139. Word Break
377. Combination Sum IV(顺序+完全背包)