- 单词拆分(需二刷)
解题过程中出现的问题:
1、递推公式的确定 dp[i] = true表示长度为i的字符串可以拆分出现的单词 如果 dp[j] 为 true 且 [j, i]出现在字典里
2、背包容量应从1开始
3、内层循环中 循环条件中少了 背包容量 > 物品
4、建立unorder_set集合 用 .find()函数确定tmp是否在集合中
成功通过代码如下:
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordlist(wordDict.begin(), wordDict.end());
// dp[i] = true表示长度为i的字符串可以拆分出现的单词
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 tmp = s.substr(j, i - j); //substr(起始位置,长度)
// 如果 dp[j] 为 true 且 [j, i]出现在字典里
if(wordlist.find(tmp) != wordlist.end() && dp[j]) dp[i] = true;
}
}
return dp[s.size()];
}
};
· 多重背包
(把背包里的东西摊开来 就变成01背包)
void test3()
{
vector<int> weight = { 1, 3, 4 };
vector<int> value = { 15, 20, 30 };
vector<int> nums = { 2, 3, 2 };
int bagWeight = 10;
for (int i = 0; i < nums.size(); i++)
{
while (nums[i] > 1)
{
value.push_back(value[i]);
weight.push_back(weight[i]);
nums[i]--;
}
}
vector<int> dp(bagWeight + 1, 0);
for (int i = 0; i < weight.size(); i++)
{
for (int j = bagWeight; j >= weight[i]; j--)
{
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
}
}
cout << dp[bagWeight] << endl;