139. 单词拆分
题解
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
vector<bool> dp(s.size() + 1,false);
dp[0] = true;
for(int j = 1;j <= s.size();j++)
{
for(int i = 0;i < j;i++)
{
string word = s.substr(i,j - i);
if(find(wordDict.begin(),wordDict.end(),word) != wordDict.end() && dp[i] == true)
{
dp[j] = true;
}
}
}
return dp[s.size()];
}
};
思路
① dp[j] : 字符串长度为j的话,若dp[j]为true,表示可以拆分为一个或多个在wordDict中出现的单词;否则,表示不可以拆分为一个或多个在wordDict中出现的单词。
② 递推公式:
if(s在[j, i] 这个区间的子串出现在wordDict里 && dp[i]是true) 那么 dp[j] = true。
③ 遍历顺序:
由于单词可以重复使用,因此为完全背包;
由于dp[j]与单词顺序有关,因此为求排列。
所以遍历顺序为外层为背包,内层为物品。
注意
① 不可以直接判断s在[j, i] 这个区间的子串与wordDict按顺序遍历的单词是否相同,因为s在[j, i] 这个区间的子串不一定是按照wordDict的顺序出现的,因此需要find(wordDict.begin(),wordDict.end(),word) != wordDict.end()
来表示s在[j, i] 这个区间的子串出现在wordDict里
②if中的条件判断的是dp[i] == true,不是dp[j - 1] == true
多重背包
1.定义:
有N种物品和一个容量为V 的背包。第i种物品最多有Mi件可用,每件耗费的空间是Ci ,价值是Wi 。求解将哪些物品装入背包可使这些物品的耗费的空间 总和不超过背包容量,且价值总和最大。
2.与01背包的相似之处:
每件物品最多有Mi件可用,把Mi件摊开,就变成了01背包问题。