class Solution {
public:
int lastStoneWeightII(vector<int>& stones) {
int dp[15001]={0};//表示容积为j的背包最多能装石头的重量
int sum=0;
for(int i=0;i<stones.size();i++){
sum+=stones[i];
}
int target=sum/2;
//遍历物品
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]*2;
}
};
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int target) {
int sum=0;
for(int i=0;i<nums.size();i++)
sum+=nums[i];
if((sum+target)%2!=0) return 0;
if(abs(target)>sum) return 0;
int x=(sum+target)/2;
int dp[22][1002]={0};//用下标0-i的数字填满j背包有多少种方法
//初始化
if(nums[0]<=x) dp[0][nums[0]]=1;
dp[0][0]=1;
int zero=0;
for(int i=0;i<nums.size();i++){
if(nums[i]==0){
zero++;
}
//表示当前的0的物品数量
dp[i][0]=pow(2,zero);
}
//遍历
for(int i=1;i<nums.size();i++){
for(int j=1;j<=x;j++){
if(j>=nums[i])
dp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i]];
else//只能不使用
dp[i][j]=dp[i-1][j];
}
}
return dp[nums.size()-1][x];
}
};
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> dp(m + 1, vector<int> (n + 1, 0)); // 默认初始化0
for (string str : strs) { // 遍历物品
int oneNum = 0, zeroNum = 0;
for (char c : str) {
if (c == '0') zeroNum++;
else oneNum++;
}
for (int i = m; i >= zeroNum; i--) { // 遍历背包容量且从后向前遍历!
for (int j = n; j >= oneNum; j--) {
dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
}
}
}
return dp[m][n];
}