Day44 动态规划第六天
LeetCode 322.零钱兑换
dp数组的含义:装满容量为j的背包需要的最少物品数为dp[j]
递推公式:dp[j]=min(dp[j-coins[i]]+1,dp[j])
初始化:dp[0]=0,dp[j]=INT_MAX
遍历顺序:个数问题与遍历顺序无关,都可以
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-coins[i]]+1,dp[j]);
}
}
}
if(dp[amount]==INT_MAX) return -1;
return dp[amount];
}
};
LeetCode 279.完全平方数
与零钱兑换几乎一致,区别就只有物品变成了完全平方数(ixi)了。
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];
}
};
LeetCode139.单词拆分
dp数组含义:如果长度为i的字符串能被字典里的单词表示,dp[i]==true。
递推公式:if([j,i]是字典里的单词 dp[j]==true) dp[i]=true;
初始化:dp[0]=true,dp[i]=false
遍历顺序:先背包,后物品,从后往前
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 word=s.substr(j,i-j);
if(wordSet.find(word)!=wordSet.end() && dp[j]){
dp[i]=true;
}
}
}
return dp[s.size()];
}
};
强化完全背包!