§Problem
-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
int n = coins.size();
if (n == 0)
return -1;
sort(coins.rbegin(),coins.rend());
vector<int> dp(amount+1, amount+1);
dp[0] = 0;
for (auto coin : coins)
for (int w = coin; w <= amount; ++w)
dp[w] = min(dp[w], dp[w-coin]+1);
return dp[amount] > amount ? -1 : dp[amount];
}
};Others:
1
2
3
4// if coin[1000, 2000], there is no need for i starting at 0
// coins[0] + 1 may overflow if coins[0] == Integer.MAX_VALUE
for (int i = coins[0]; i <= amount; i++) {
for (int coin : coins) { -
377. Combination Sum IV, similar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
int n = nums.size();
if (n == 0)
return 0;
sort(nums.begin(),nums.end());
vector<int> dp(target+1, 0);
dp[0] = 1;
/* remove duplicate.
eg. 1 1 2 = 1 2 1, since 1 will not consider again
for (auto num : nums)
for (int w = num; w <= target; ++w)
*/
for (int w = nums[0]; w <= target; ++w)
for (auto num : nums){
if (w < num)
break;
dp[w] += dp[w-num];
}
return dp[target];
}
}; -
DP
- Deduction Formula
- Initialization
- Space Improvement (Bonus)
- Audible 题:BugdetShopping
n dollars, bundleQuantities array, bundleCosts array
eg. Helen has n = 50 dollars to purchase notebooks from 2 stores described by bundleQunantities = [20, 19] and bundleCost = [24, 20]. She makes the following purchases:
One bundle of 20 notebooks from shop 0 at a cost 24 dollars and has 50 – 24 = 26 dollars left.
Another bundle of 20 notebooks from shop 0 at a cost 24 dollars and has 26 – 24 = 2 dollars left.
Helen can’t afford any more notebooks, so we return the total number of notebooks she was able to purchase: 20 + 20 = 40.1
2
3// f(i) is the maximum number of notebook given i dollar
f[i] = max(f[i – b.cost] + b.quantity) given different b
maxf = 0, maxf = max(maxf, f[i])1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23int max = 0;
int[] f = new int[n + 1];
for (int i = bundles[0].cost; i < f.length; i++) {
for (Bundle b : bundles) {
if (b.cost > i) {
break;
}
if (i == b.cost) {
f[i] = Math.max(f[i], b.quantity);
max = Math.max(max, f[i]);
}
int c = f[i - b.cost];
if (c == 0) {
continue;
}
f[i] = Math.max(f[i], c + b.quantity);
System.out.println(i + "=" + f[i]);
max = Math.max(max, f[i]);
}
}
Coin Change is unlimited, while Knapsack is limited
-
背包问题
- Backpack
Given n items with size Ai, an integer m denotes the size of a backpack. How full you can fill this backpack?
1
2
3i = [0, A.length)
j = [m, A[i]]
result[j] = max(result[j-A[i]]+A[i], result[j])-
Backpack II
Given n items with size Ai and value Vi, and a backpack with size m. What’s the maximum value can you put into the backpack?
Example
Given 4 items with size [2, 3, 5, 7] and value [1, 5, 2, 4], and a backpack with size 10. The maximum value is 9.1
2
3i = [0, A.length)
j = [m, A[i]]
result[j] = max(result[j-A[i]]+v[i], result[j]) -
https://en.wikipedia.org/wiki/Knapsack_problem
https://www.geeksforgeeks.org/knapsack-problem
https://brilliant.org/wiki/backpack-problem
- Backpack
-
背包问题变种
-
maximize chossedn string -> m’s 1, n’s 0
1
2
3for k=1..l
i=m..s0, j=n..s1
dp[i][j] = max(dp[i][j],dp[i-s0][j-s1]+1)// wo/w s -
+/- ai = s
1
2
3
4
5
6
7sum(P) - sum(N) = target
sum(P) + sum(N) + sum(P) - sum(N) = target + sum(P) + sum(N)
2 * sum(P) = target + sum(nums)
for num:nums
for w = (t+s)/2 ... num
dp[w] += dp[w-num] -
416. Partition Equal Subset Sum
find if the array can be partitioned into two subsets, that sum is equal
1
2
3
4
5sum(subset1) = sum/2
for num:nums
for w = sum/2 ... num
dp[w] = dp[w]|dp[w-num]
-
§Thinking
-
DP
-
先枚举物品,再枚举容量。
eg. [1, 2, 3] 组合4时,(1, 1, 2) == (1, 2, 1)。因为同一个物体不会再次考虑1
2
3
4
5/* remove duplicate.
eg. 1 1 2 = 1 2 1, since 1 will not consider again
for (auto num : nums)
for (int w = num; w <= target; ++w)
*/ -
先枚举容量,再枚举物品。
1
2for (int w = nums[0]; w <= target; ++w)
for (auto num : nums)
-
-
背包问题:
- 枚举物品
- 枚举容量
增序枚举,重复装入某个物品,而且尽可能多的,使价值最大
逆序枚举:物品至多装一次