-
Notifications
You must be signed in to change notification settings - Fork 49
Expand file tree
/
Copy pathBackpack VIII.java
More file actions
174 lines (160 loc) · 4.99 KB
/
Backpack VIII.java
File metadata and controls
174 lines (160 loc) · 4.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
Description
Give some coins of different value and their quantity.
Find how many values which are in range 1 ~ n can these coins be combined
Example
Given:
n = 10
value = [1,2,4]
amount = [2,1,1]
Return: 8
They can combine all the values in 1 ~ 8
Tags
Backpack Dynamic Programming
*/
/**
* Approach: Multiple Backpack
* 该题属于多重背包问题。
* dp[i][j]表示:在前 i 个元素中,取得价值为 j 的方案是否成立
* 因此 dp[i][j] |= dp[i - 1][j - k * value[i]] (j >= k * value[i])
* 最后我们只需要统计 dp[n-1][m] 中有几个方案为 true 即可。
*
* 注意点:题目要求至少取一个值,即全部都不取(结果为0)的方案是不成立的
* 而我们这里是认为一个都不取的方案是成立的,因此结果需要 减去1.
*
* 关于 多重背包问题 的详细解析与解法优化可以参考:
* https://github.com/cherryljr/LintCode/edit/master/Backpack%20VII.java
*/
public class Solution {
/**
* @param m: the value from 1 - m
* @param value: the value of coins
* @param amount: the number of coins
* @return: how many different value
*/
public int backPackVIII(int m, int[] value, int[] amount) {
int n = value.length;
boolean[][] dp = new boolean[n][m + 1];
// Initialize
for (int i = 0; i <= amount[0]; i++) {
if (i * value[0] <= m) {
dp[0][i * value[0]] = true;
}
}
// Function
for (int i = 1; i < n; i++) {
for (int j = 0; j <= m; j++) {
for (int k = 0; k <= amount[i]; k++) {
if (j >= k * value[i]) {
dp[i][j] |= dp[i - 1][j - k * value[i]];
} else {
// 如果当前价值超过了总价值 j,那么后面就没有继续计算的必要了
break;
}
}
}
}
// Answer
int rst = 0;
for (int i = 0; i <= m; i++) {
if (dp[n - 1][i]) {
rst++;
}
}
return rst - 1;
}
}
/**
* Approach 2: Multiple Backpack (Using 01 Backpack)
*/
public class Solution {
/**
* @param m: the value from 1 - m
* @param value: the value of coins
* @param amount: the number of coins
* @return: how many different value
*/
public int backPackVIII(int m, int[] value, int[] amount) {
int n = value.length;
boolean[] dp = new boolean[m + 1];
// Initialize
for (int i = 0; i <= amount[0]; i++) {
if (i * value[0] <= m) {
dp[i * value[0]] = true;
}
}
// Function
for (int i = 1; i < n; i++) {
for (int k = 0; k < amount[i]; k++) {
for (int j = m; j >= value[i]; j++) {
dp[j] |= dp[j - value[i]];
}
}
}
// Answer
int rst = 0;
for (int i = 0; i <= m; i++) {
if (dp[i]) {
rst++;
}
}
return rst - 1;
}
}
/**
* Approach 3: Multiple Backpack (Using Binary Code)
* 使用 二进制 的思想对时间复杂度进行优化
*/
public class Solution {
/**
* @param m: the value from 1 - m
* @param value: the value of coins
* @param amount: the number of coins
* @return: how many different value
*/
public int backPackVIII(int m, int[] value, int[] amount) {
int n = value.length;
boolean[] dp = new boolean[m + 1];
// Initialize
for (int i = 0; i <= amount[0]; i++) {
if (i * value[0] <= m) {
dp[i * value[0]] = true;
}
}
// Function
for (int i = 1; i < n; i++) {
if (value[i] * amount[i] > m) {
completedBackpack(dp, value[i], m);
} else {
int k = 1;
while (k < amount[i]) {
zeroOneBackpack(dp, k * value[i], m);
amount[i] -= k;
k <<= 1; // 二进制的思想
}
// 最后对余数部分进行一次 01背包 处理
zeroOneBackpack(dp, amount[i] * value[i], m);
}
}
// Answer
int rst = 0;
for (int i = 0; i <= m; i++) {
if (dp[i]) {
rst++;
}
}
return rst - 1;
}
// 完全背包问题代码
private void completedBackpack(boolean[] dp, int price, int m) {
for (int j = price; j <= m; j++) {
dp[j] |= dp[j - price];
}
}
// 01背包问题代码
private void zeroOneBackpack(boolean[] dp, int price, int m) {
for (int j = m; j >= price; j--) {
dp[j] |= dp[j - price];
}
}
}