问题描述
- 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成
两个子集
,使得两个子集的元素和相等
。
示例 1:
输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。
示例 2:
输入:nums = [1,2,3,5]
输出:false
解释:数组不能分割成两个元素和相等的子集。
class Solution {
public:
bool canPartition(vector<int>& nums) {
int n = nums.size();
if (n < 2) {
return false;
}
int sum = accumulate(nums.begin(), nums.end(), 0);
int maxNum = *max_element(nums.begin(), nums.end());
if (sum & 1) {
return false;
}
int target = sum / 2;
if (maxNum > target) {
return false;
}
//dp[i][j]:在考虑i+1件物品之后,是否能“正好”得到j的重量
vector<vector<int>> dp(n, vector<int>(target + 1, 0));// all init to 0
for (int i = 0; i < n; i++) {
dp[i][0] = true;
}
dp[0][nums[0]] = true;// 只考虑第一件物品,下边的循环从第二件物品开始
for (int i = 1; i < n; i++) {
int num = nums[i];
for (int j = 1; j <= target; j++) {
if (j >= num) {
dp[i][j] = dp[i - 1][j] | dp[i - 1][j - num];
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[n - 1][target];
}
};


CG
- https://www.bilibili.com/video/BV1C7411K79w?p=1



dp[i][j]表示背包容量为j, 考虑到第i件物品 时的价值
装有i件物品


// 0-1背包(动态规划) https://blog.youkuaiyun.com/qq_38984851/article/details/81133096
using namespace std;
int w[105], val[105];
int dp[105][1005];
int main()
{
int t, m, res=-1;
cin >> t >> m;
for(int i=1; i<=m; i++)
cin >> w[i] >> val[i];
for(int i=1; i<=m; i++) //物品
for(int j=t; j>=0; j--) //容量
{
if(j >= w[i])
dp[i][j] = max(dp[i-1][j-w[i]]+val[i], dp[i-1][j]);
else //只是为了好理解
dp[i][j] = dp[i-1][j];
}
cout << dp[m][t] << endl;
return 0;
}