java动态规划(背包问题)
5kg的袋子
物品:物品只有一个,且不能拆分。
钱:6 10 12
Kg:1 2 4
我们把5kg袋子拆分成1kg 1kg这样的来计算,每个格子的意思就是当前袋子在这个容量下能装的最大价值。
行表示每次加的物品
1kg | 2kg | 3kg | 4kg | 5kg | |
---|---|---|---|---|---|
加第一个物品 | 6 | 6 | 6 | 6 | 6 |
加第二个物品 | 6(取上面第一个) | 10 | 16 | 16 | 16 |
加第三个物品 | 6 | 10 | 16 | 16 | 18 |
第二个进来时,如果此时袋子为2kg,我们知道在第一个物品进来时,2kg最多能装6块钱。,这时候如果我们选择装第二物品那么袋子里面的钱为10块,然后剩余0kg,那么物品1就不能装了。然后发现10块大于袋子里面原来的6快,所以我们选择装第二个 丢掉第一个。
第三个物品进来,如果此时袋子为5kg,我们如果选择加第三个物品,那么袋子容积还剩1kg,能得12块,我们找到上一列1kg袋子的最大价值,为6,所以总的为18.
核心思想:
分解子问题,通过局部最大值得到全局最大。
public class Dq {
//动态规划
public static void main(String[] args) {
int value[] = {60,100,120}; //每个物品的钱
int weight[] = {10,20,40}; //每个物品的重量 和上面的一一对应
int w = 50; //袋子的容积
int n = 3; //物品的个数
int dp[][] = new int[n+1][w+1]; //表示分割,成一个 小的表格
for(int i = 1; i<=n ;i++) { //表示物品往里面加
for(int cw = 1; cw <= w; cw ++) { //袋子在每一个容积下所装的最大的钱
if(weight[i - 1] <= cw) { //表示这个物品可以装
dp[i][cw] = Math.max(
value[i-1]+dp[i-1][cw-weight[i-1]], //我装新加的物品
dp[i-1][cw] //我不装这个新加的这个物品
);
}else {
dp[i][cw] = dp[i-1][cw]; //新加的这个装不下 ,那么就取前一个物品装值
}
}
}
System.out.println("袋子能装的最大价值:" + dp[n][w]);
}
}