|
1 | 1 | M |
| 2 | +1518497606 |
2 | 3 |
|
3 | | -做了Backpack I, 这个就如出一辙。 |
4 | | -想法还是,选了A[i-1] 或者没选A[i]. |
5 | | -一路往前跑不回头。就出来了。 |
6 | | -其实这个Backpack II 还更容易看懂代码。 |
| 4 | +做了Backpack I, 这个就如出一辙, 只不过: dp存的不是w可否存成功true/false. dp存的是加上sum value的最大值. |
| 5 | +想法还是,选了A[i - 1] 或者没选A[i - 1]时候不同的value值. |
7 | 6 |
|
8 | 7 | O(m)的做法: |
9 | | -想想,的确我们只care 最后一行,所以一个存value的就够了。 |
10 | | -注意:和bakcpackI的 O(m)一样的,j是倒序的。如果没有更好的j,就不要更新。就是这个道理。 |
| 8 | +想想,的确我们只care 最后一行,所以一个存value的就够了. |
| 9 | +注意:和bakcpackI的 O(m)一样的,j是倒序的。如果没有更好的j,就不要更新。就是这个道理. |
| 10 | + |
| 11 | +注意: 如果无法达到的w, 应该mark as impossible. 一种简单做法是mark as -1 in dp. |
| 12 | +如果有负数value, 就不能这样, 而是要开一个can[i][w]数组, 也就是backpack I 的原型. |
11 | 13 |
|
12 | 14 |
|
13 | 15 | ``` |
|
30 | 32 | LintCode Copyright Dynamic Programming Backpack |
31 | 33 | */ |
32 | 34 |
|
| 35 | +/* |
| 36 | +Thoughts: |
| 37 | +Dealing with value, the dp[i][w] = max value that can be formed over i tems at weight w. |
| 38 | +Two conditions: |
| 39 | +1. didn't pick A[i - 1]: dp[i - 1][w], value sum does not change. |
| 40 | +2. Picked A[i - 1]: dp[i - 1][w - A[i - 1]] + V[i - 1]; |
| 41 | +Find the max of the above two, and record. |
| 42 | +Initialize with dp[0][0] = -1: not possible to form w, so mark as -1, impossible. |
| 43 | +*/ |
| 44 | + |
| 45 | +public class Solution { |
| 46 | + public int backPackII(int m, int[] A, int V[]) { |
| 47 | + if (A == null || V == null || A.length != V.length) { |
| 48 | + return 0; |
| 49 | + } |
| 50 | + int n = A.length; |
| 51 | + int[][] dp = new int[n + 1][m + 1]; // [5][5] |
| 52 | + |
| 53 | + for (int j = 0; j <= m; j++) { |
| 54 | + dp[0][j] = -1; // 0 items cannot form weight j, hence value -1, marking impossible |
| 55 | + } |
| 56 | + dp[0][0] = 0; // 0 items, 0 weight -> 0 value |
| 57 | + |
| 58 | + for (int i = 1; i <= n; i++) { |
| 59 | + for (int j = 1; j <= m; j++) { |
| 60 | + dp[i][j] = dp[i - 1][j]; // 0 |
| 61 | + if (j - A[i - 1] >= 0 && dp[i - 1][j - A[i - 1]] != -1) { |
| 62 | + dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - A[i - 1]] + V[i - 1]); |
| 63 | + } |
| 64 | + |
| 65 | + } |
| 66 | + } |
| 67 | + |
| 68 | + int rst = 0; |
| 69 | + for (int j = 0; j <= m; j++) { |
| 70 | + if (dp[n][j] != -1) { |
| 71 | + rst = Math.max(rst, dp[n][j]); |
| 72 | + } |
| 73 | + } |
| 74 | + return rst; |
| 75 | + } |
| 76 | +} |
| 77 | + |
| 78 | +// Rolling array |
| 79 | +public class Solution { |
| 80 | + public int backPackII(int m, int[] A, int V[]) { |
| 81 | + if (A == null || V == null || A.length != V.length) { |
| 82 | + return 0; |
| 83 | + } |
| 84 | + int n = A.length; |
| 85 | + int[][] dp = new int[2][m + 1]; |
| 86 | + for (int j = 0; j <= m; j++) { |
| 87 | + dp[0][j] = -1; // 0 items cannot form weight j, hence value -1, mark as impossible |
| 88 | + } |
| 89 | + dp[0][0] = 0; // 0 items, 0 weight -> 0 value |
| 90 | + int curr = 0, prev; |
| 91 | + |
| 92 | + for (int i = 1; i <= n; i++) { |
| 93 | + // rolling index |
| 94 | + prev = curr; |
| 95 | + curr = 1 - prev; |
| 96 | + for (int j = 1; j <= m; j++) { |
| 97 | + dp[curr][j] = dp[prev][j]; // 0 |
| 98 | + if (j - A[i - 1] >= 0 && dp[prev][j - A[i - 1]] != -1) { |
| 99 | + dp[curr][j] = Math.max(dp[curr][j], dp[prev][j - A[i - 1]] + V[i - 1]); |
| 100 | + } |
| 101 | + } |
| 102 | + } |
| 103 | + |
| 104 | + int rst = 0; |
| 105 | + for (int j = 0; j <= m; j++) { |
| 106 | + if (dp[curr][j] != -1) { |
| 107 | + rst = Math.max(rst, dp[curr][j]); |
| 108 | + } |
| 109 | + } |
| 110 | + return rst; |
| 111 | + } |
| 112 | +} |
| 113 | + |
| 114 | + |
| 115 | + |
| 116 | + |
| 117 | + |
| 118 | +/* |
| 119 | +Initialize with dp[0][0] = 0. |
| 120 | +This will pass the test, however it's not 100% explicit |
| 121 | +*/ |
| 122 | +public class Solution { |
| 123 | + public int backPackII(int m, int[] A, int V[]) { |
| 124 | + if (A == null || V == null || A.length != V.length) { |
| 125 | + return 0; |
| 126 | + } |
| 127 | + int n = A.length; |
| 128 | + int[][] dp = new int[n + 1][m + 1]; // [5][5] |
| 129 | + dp[0][0] = 0; // 0 items, 0 weight -> 0 value |
| 130 | + for (int j = 0; j <= m; j++) { |
| 131 | + dp[0][j] = 0; // 0 items cannot form weight j, hence value 0 |
| 132 | + } |
| 133 | + |
| 134 | + for (int i = 1; i <= n; i++) { |
| 135 | + for (int j = 1; j <= m; j++) { |
| 136 | + dp[i][j] = dp[i - 1][j]; // 0 |
| 137 | + if (j - A[i - 1] >= 0) { |
| 138 | + dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - A[i - 1]] + V[i - 1]); |
| 139 | + } |
| 140 | + } |
| 141 | + } |
| 142 | + return dp[n][m]; |
| 143 | + } |
| 144 | +} |
| 145 | + |
| 146 | +// Rolling array |
| 147 | +public class Solution { |
| 148 | + public int backPackII(int m, int[] A, int V[]) { |
| 149 | + if (A == null || V == null || A.length != V.length) { |
| 150 | + return 0; |
| 151 | + } |
| 152 | + int n = A.length; |
| 153 | + int[][] dp = new int[2][m + 1]; // [5][5] |
| 154 | + dp[0][0] = 0; // 0 items, 0 weight -> 0 value |
| 155 | + for (int j = 0; j <= m; j++) { |
| 156 | + dp[0][j] = 0; // 0 items cannot form weight j, hence value 0 |
| 157 | + } |
| 158 | + int curr = 0, prev; |
| 159 | + |
| 160 | + for (int i = 1; i <= n; i++) { |
| 161 | + // rolling index |
| 162 | + prev = curr; |
| 163 | + curr = 1 - prev; |
| 164 | + for (int j = 1; j <= m; j++) { |
| 165 | + dp[curr][j] = dp[prev][j]; // 0 |
| 166 | + if (j - A[i - 1] >= 0) { |
| 167 | + dp[curr][j] = Math.max(dp[curr][j], dp[prev][j - A[i - 1]] + V[i - 1]); |
| 168 | + } |
| 169 | + } |
| 170 | + } |
| 171 | + return dp[curr][m]; |
| 172 | + } |
| 173 | +} |
| 174 | + |
33 | 175 |
|
34 | 176 | /* |
| 177 | +Previous Notes. |
35 | 178 | Thoughts: |
36 | 179 | In Backpack I, we store true/false to indicate the largest j in last dp row. |
37 | 180 | Here, we can store dp[i][j] == max value. |
|
0 commit comments