问题描述:N种物品,每种物品只有1个,每个物品有自己的重量和价值,有一个最多只能放重量为M的背包。问:这个背包最多能装价值为多少的物品?
二维dp数组解法:
优化为一维dp数组:
LeetCode题目:
分割等和子集https://leetcode.cn/problems/partition-equal-subset-sum/
class Solution {
public:
bool canPartition(vector& nums) {
int sum = accumulate(nums.begin(), nums.end(), 0);
if (sum % 2 != 0)
return false;
int target = sum / 2;
vector dp(target + 1, 0);
for (int i = 0; i < nums.size(); i++) {
for (int j = target; j >= nums[i]; j--) {
dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
}
}
if (dp[target] == target)
return true;
return false;
}
};
最后一块石头的重量IIhttps://leetcode.cn/problems/last-stone-weight-ii/description/
class Solution {
public:
int lastStoneWeightII(vector& stones) {
int sum = accumulate(stones.begin(), stones.end(), 0);
int target = sum / 2;
vector dp(target + 1, 0);
for (int i = 0; i < stones.size(); i++) {
for (int j = target; j >= stones[i]; j--) {
dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
}
}
return sum - dp[target] - dp[target];
}
};
目标和https://leetcode.cn/problems/target-sum/description/
本题dp数组怎么来的?
sum(P) - sum(N) = target
sum(P) + sum(N) + sum(P) - sum(N) = target + sum(P) + sum(N)
2 * sum(P) = target + sum(nums)
class Solution {
public:
int findTargetSumWays(vector& nums, int target) {
int sum = accumulate(nums.begin(), nums.end(), 0);
if ((sum + target) % 2 != 0)
return 0;
int pos = (sum + target) / 2;
if (pos < 0)
return 0;
vector dp(pos + 1, 0);
dp[0] = 1;
for (int i = 0; i < nums.size(); i++) {
for (int j = pos; j >= nums[i]; j--) {
dp[j] += dp[j - nums[i]];
}
}
return dp[pos];
}
};
一和零https://leetcode.cn/problems/ones-and-zeroes/
class Solution {
public:
int findMaxForm(vector& strs, int m, int n) {
vector> dp(m + 1, vector(n + 1, 0));
for (auto stri : strs) {
int x = 0, y = 0;
for (auto chi : stri) {
if (chi == '0') {
x++;
} else {
y++;
}
}
for (int i = m; i >= x; i--) {
for (int j = n; j >= y; j--) {
dp[i][j] = max(dp[i][j], dp[i - x][j - y] + 1);
}
}
}
return dp[m][n];
}
};