目录
1049. 最后一块石头的重量 II (0-1背包)
题目链接:1049. 最后一块石头的重量 II
老觉得这个题可以排序、做差什么的用贪心来做!看过题解发现确实有,倒还不如转为为0-1背包。
二维dp数组
int calculate_sum(int* stones, int stonesSize){
int sum=0;
for(int i=0;i<stonesSize;i++){
sum+=stones[i];
}
return sum;
}
int lastStoneWeightII(int* stones, int stonesSize){
int sum=calculate_sum(stones,stonesSize);
int target=sum/2;
int dp[stonesSize][target+1];
//初始化dp数组
for(int i=0;i<stonesSize;i++){
dp[i][0]=0;
}
int i=0;
for(;i<target&&i<stones[0];i++){
dp[0][i]=0;
}
for(;i<=target;i++){
dp[0][i]=stones[0];
}
//填充dp数组
for(int i=1;i<stonesSize;i++){
for(int j=1;j<=target;j++){
if(j-stones[i]>=0){
dp[i][j]=fmax(dp[i-1][j],dp[i-1][j-stones[i]]+stones[i]);
}else{
dp[i][j]=dp[i-1][j];
}
}
}
return fabs(2*dp[stonesSize-1][target]-sum);
}
一维dp数组(没有二维好理解)
int calculate_sum(int* stones, int stonesSize){
int sum=0;
for(int i=0;i<stonesSize;i++){
sum+=stones[i];
}
return sum;
}
int lastStoneWeightII(int* stones, int stonesSize){
int sum=calculate_sum(stones,stonesSize);
int target=sum/2;
int* dp=(int*)malloc(sizeof(int)*(target+1));
memset(dp,0,sizeof(int)*(target+1));
for(int i=0;i<stonesSize;i++){
for(int j=target;j>=stones[i];j--){
dp[j]=fmax(dp[j],dp[j-stones[i]]+stones[i]);
}
}
return fabs(2*dp[target]-sum);
}
494. 目标和
题目链接:494. 目标和
题目描述:
给你一个整数数组 nums 和一个整数 target 。
向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :
例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。
返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。
这些应用题要想到怎么转化成0-1背包的问题真难呀!
nums数组中一部分元素取正,一部分元素取负有如下两个等式成立:(等式左边两求和的元素没有正负之分,只取元素值)
由上面两个等式得出:
等式右边值可求得,就能转化为0-1背包问题:nums数组中子集和=目标值有几种方案。
递推公式:
int calculate(int* nums,int numsSize,int target){
int sum=0;
for(int i=0;i<numsSize;i++){
sum+=nums[i];
}
return sum+=target;
}
int findTargetSumWays(int* nums, int numsSize, int target){
int sum=calculate(nums,numsSize,target);
if(sum<0||sum%2) return 0;
sum/=2;
int* dp=(int*)malloc(sizeof(int)*(sum+1));
memset(dp,0,sizeof(int)*(sum+1));
//dp[0]要初始化为1
dp[0]=1;
for(int i=0;i<numsSize;i++){
for(int j=sum;j>=nums[i];j--){
dp[j]+=dp[j-nums[i]];
}
}
return dp[sum];
}
474.一和零(先不做)
死乞白赖做了也白做!不会还是不会,前面都没学好