动态规划刷题复习
一、01背包
- 416. 分割等和子集
- 1049. 最后一块石头的重量 II
- 494. 目标和
- 474. 一和零
416. 分割等和子集
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum=0;
for(int i=0;i<nums.size();i++) {
sum+=nums[i];
}
if(sum%2!=0)
return false;
vector<int> dp(sum/2+1,0);
for(int i=0;i<nums.size();i++) {
for(int j=sum/2;j>=nums[i];j--) {
dp[j] = max(dp[j],dp[j-nums[i]]+nums[i]);
}
}
if(dp[sum/2]==sum/2)
return true;
else
return false;
}
};
1049. 最后一块石头的重量 II
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,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];
}
};
494. 目标和
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int target) {
int sum=0;
for(int i=0;i<nums.size();i++)
sum+=nums[i];
int x = (sum+target)/2;
vector<int> dp(x+1,0);
dp[0]=1;
for(int i=0;i<nums.size();i++) {
for(int j=x;j>=nums[i];j--) {
dp[j] += dp[j-nums[i]];
}
}
return dp[x];
}
};
474. 一和零
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> dp(m+1,vector<int>(n+1,0));
for(string s : strs){
int num_0=0,num_1=0;
for(char c : s) {
if(c=='0')
num_0++;
else if(c=='1')
num_1++;
}
for(int i=m;i>=num_0;i--) {
for(int j=n;j>=num_1;j--) {
dp[i][j] = max(dp[i][j], dp[i-num_0][j-num_1]+1);
}
}
}
return dp[m][n];
}
};
二、完全背包问题
- 518 零钱兑换Ⅱ
题目要求:符合 32 位整数范围; - 377.组合总和Ⅳ
- 70 爬楼梯 完全背包问题版本
- 322.零钱兑换
- 279.完全平方数
for循环中 j的界限从1开始 - 139.单词拆分
这个题对unordered_set的使用以及dp[i]的更新还是不熟练
518 零钱兑换Ⅱ
class Solution {
public:
int change(int amount, vector<int>& coins) {
vector<int> dp(amount+1,0);
dp[0]=1;
for(int i=0;i<coins.size();i++) {
for(int j=coins[i];j<=amount;j++) {
dp[j] += dp[j-coins[i]];
}
}
return dp[amount];
}
};
377.组合总和Ⅳ
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target+1,0);
dp[0] = 1;
for(int i=0;i<=target;i++) {
for(int j=0;j<nums.size();j++) {
if(nums[j]<=i && dp[i] < INT_MAX-dp[i-nums[j]])
dp[i] += dp[i-nums[j]];
}
}
return dp[target];
}
};
70 爬楼梯 完全背包问题版本
class Solution {
public:
int climbStairs(int n) {
vector<int> dp(n+1,0);
dp[0]=1;
for(int i=1;i<=n;i++) {
for(int j=1;j<=2;j++) {
if(i-j>=0)
dp[i] += dp[i-j];
}
}
return dp[n];
}
};
322.零钱兑换
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount+1,INT_MAX);
dp[0]=0;
for(int i=0;i<coins.size();i++) {
for(int j=coins[i];j<=amount;j++) {
if(dp[j-coins[i]]!=INT_MAX)
dp[j] = min(dp[j],dp[j-coins[i]]+1);
}
}
if(dp[amount]==INT_MAX)
return -1;
return dp[amount];
}
};
279.完全平方数
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n+1,INT_MAX);
dp[0]=0;
for(int i=0;i<=n;i++) {
for(int j=1;j*j<=i;j++) {
dp[i] = min(dp[i-j*j]+1,dp[i]);
}
}
return dp[n];
}
};
139.单词拆分
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordSet(wordDict.begin(),wordDict.end());
vector<bool> dp(s.size()+1,false);
dp[0]=true;
for(int i=1;i<=s.size();i++) {
for(int j=0;j<i;j++) {
string substr1 = s.substr(j,i-j);
if(wordSet.find(substr1)!=wordSet.end() && dp[j])
dp[i] = true;
}
}
return dp[s.size()];
}
};