代码改变世界

0-1背包问题

2022-05-13 16:59  钟铧若岩  阅读(38)  评论(0编辑  收藏  举报

 

 1 package com.company;
 2 
 3 import org.junit.Test;
 4 
 5 public class BeiBao01 {
 6 
 7 
 8     /*
 9     * 根据之前已经引出的状态转移方程,我们再来理解一遍,对于编号为 i 的物品:
10 
11 如果选择它,那么,当前背包的最大价值等于” i 号物品的价值“ 加上 ”减去 i 号物品占用的空间后剩余的背包空间所能存放的最大价值“,即dp[i][k] = value[i] + dp[i-1][k-weight[i]];
12 
13 如果不选择它,那么,当前背包的价值就等于前 i-1 个物品存放在背包中的最大价值,即 dp[i][k] = dp[i-1][k]
14 
15 dp[i][k] 的结果取两者的较大值,即:
16 
17 dp[i][k] = max(value[i] + dp[i-1][k-weight[i]], dp[i-1][k])
18     *
19     * */
20 
21     public int maxValue(int[] weight, int[] value, int W) {
22         //这里假定传入的weight和values数组长度总是一致的
23         int n = weight.length;
24         if (n == 0) return 0;
25 
26         int[][] dp = new int[n + 1][W + 1];
27         for (int i = 1; i <= n; i++) {
28             for (int k = 1; k <= W; k++) {
29                 // 存放 i 号物品(前提是放得下这件物品)
30                 int valueWith_i = (k - weight[i - 1] >= 0) ? (value[i - 1] + dp[i - 1][k - weight[i - 1]]) : 0;
31                 // 不存放 i 号物品
32                 int valueWithout_i = dp[i - 1][k];
33                 dp[i][k] = Math.max(valueWith_i, valueWithout_i);
34                 System.out.println("i = " + i + " k = " + k);
35                 System.out.println("dp[" + i + "][" + k + "]=" + dp[i][k]);
36             }
37         }
38 
39         return dp[n][W];
40     }
41 
42     @Test
43     public void main() {
44         BeiBao01 obj = new BeiBao01();
45         int[] w = {1, 4, 3};
46         int[] v = {15, 30, 20};
47         int W = 4;
48         System.out.println(obj.maxValue(w, v, W));
49     }
50 }