class Solution {
public:
int lastStoneWeightII(vector<int>& stones) {
int sum=0;
for(int i=0;i<stones.size();i++)
{
sum+=stones[i];
}
int target=sum/2;
vector<int> dp(target+1);
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];
}
};
这道题目与风格等集相似,把石子求和进行计算,平分,两者相减就是最后的差值
(sum-dp[target])为多的那一部分dp[target]为少的一部分,两者相减即为结果
一维dp数组
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(abs(target)>sum) return 0;
if((sum+target)%2==1) return 0;
int size=(sum+target)/2;
vector<int> dp(size+1);
dp[0]=1;
for(int i=0;i<nums.size();i++)
{
for(int j=size;j>=nums[i];j--)
{
dp[j]=dp[j]+dp[j-nums[i]];
}
}
return dp[size];
}
};
二维dp数组
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(abs(target)>sum) return 0;
if((sum+target)%2==1) return 0;
int size=(sum+target)/2;
vector<vector<int>> dp(nums.size(),vector<int>(size+1));
if(nums[0]<=size)
{
dp[0][nums[0]]=1;
}
dp[0][0]=1;
int numzero=0;
for(int i=0;i<nums.size();i++)
{
if(nums[i]==0)
{
numzero++;
}
dp[i][0]=(int)pow(2.0,numzero);
}
for(int i=1;i<nums.size();i++)
{
for(int j=0;j<=size;j++)
{
if(nums[i]>j)
{
dp[i][j]=dp[i-1][j];
}
else
{
dp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i]];
}
}
}
return dp[nums.size()-1][size];
}
};
二维dp数组的递推公式为dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]];
选择物品i与不选择物品i两种,选择物品i的方法为dp[i-1][j-nums[i]],去除i物品和i物品的占背包空间,和不选择i物品和全部的物品空间