- 题目
- 给定两个长度都为N的数组weights和values,
weights[i]和values[i]分别代表 i号物品的重量和价值。
给定一个正数bag,表示一个载重bag的袋子,
你装的物品不能超过这个重量。
返回你能装下最多的价值是多少?
- 给定两个长度都为N的数组weights和values,
- 思路:
- 接收信息:cur,weight(剩余可用承重),value(已拿价值)
- 决策:每个位置选拿/不拿两个分支
- base case:如果weight<0则返回失败标记,上层对失败标记进行处理,value不加这个商品。如果cur到末尾retuen 0
- 问题:这里可以等到末尾了还有效再在list里记录当前value,中途一旦失效就不记录
- 答案:应该没有问题,最优解剩余重量>=0所以一定会达到末尾且到末尾了依然有效。但这是贪心策略
- 传递信息:cur++,weight增减,value增减
- dp:以weight,cur建表。value为值
- 普遍依赖关系:依赖下一行正下或正下往左偏weight
- 如果(rest - w[index] < 0 )
- p1=v[index] +dp[index + 1][rest - w[index]
- p2=dp[index + 1][rest];
- max(p1,p2)
- 如果(rest - w[index] < 0 )
代码
public static int dp(int[] w, int[] v, int bag) {
if (w == null || v == null || w.length != v.length || w.length == 0) {
return 0;
}
int N = w.length;
int[][] dp = new int[N + 1][bag + 1];
for (int index = N - 1; index >= 0; index--) {
for (int rest = 0; rest <= bag; rest++) {
int p1 = dp[index + 1][rest];
int p2 = 0;
int next = rest - w[index] < 0 ? -1 : dp[index + 1][rest - w[index]];
if (next != -1) {
p2 = v[index] + next;
}
dp[index][rest] = Math.max(p1, p2);
}
}
return dp[0][bag];
}