代码随想录打卡—day46—【DP】— 8.29 背包END

1 139. 单词拆分

139. 单词拆分

做了很久...估计2h 一开始我的思路卡死了 + 看题解之后的思路的详解见注释,

我的写法和carl 答案在一些微小的细节上略有不同,我的更好理解,但他的解法更简单。

我写的过程中,需要注意下标和字符串大小的关系要不要+1-1,而且dp[] 需要从1开始到n有意义,dp[0] 不管它。不可以只有0,...,n-1 这样会忽略s = "a" Dict = ["b"] 这样的样例,因为dp[0] 恒为1。

AC代码:

class Solution {
public:
    //多重背包且排列
    /*
        一开始我的思路——
        物品:字典里面str
        背包:容量为?的背包  求装满时候的情况
         dp[wordDict.size()][s.size()]
        如果n = wordDict.size() m = s.size()  又感觉要考虑每个字符和Dict中每个字符串的关系 很麻烦        
    */

    /*
        看了题解,才知道我纠结的地方 每个字符和Dict中每个字符串的关系 很麻烦,但其实可以用substr函数考虑背包的s的子串和Dict中每个字符串来比较,这样就变得很简单了。
        而且之前思考时候不知道dp[]存的值要是int还是char什么东西
        其实就题目结果反推,dp[] = trur/flase
    */
    bool dp[310];   //以i结尾的字符串是否可以利用字典中出现的单词拼接出来
    /*
        dp[j] = dp[j - wordDict[i].size()] && substr(s,j - wordDict[i].size(),wordDict[i].size()) == wordDict[i];

        dp[0] = 1;

        多重背包+排列
        背包j++ 物体i++

        模拟——
        6 7 8 9 10 11
        j = 11 size = 5 dp[6]
    */

    bool wordBreak(string s, vector<string>& wordDict) {
        dp[0] = 1;
        bool tmp[100][100];

        for(int j = 0; j <= s.size();j++)
        {
            for(int i = 0; i < wordDict.size();i++)
            {
                if(j == wordDict[i].size())  // 能装下一个
                    dp[j] =  (s.substr(j  - wordDict[i].size(),wordDict[i].size()) == wordDict[i]) || dp[j];

                else if(j > wordDict[i].size() )    // 能至少装2个 
                    dp[j] = dp[j  - wordDict[i].size()] && (s.substr(j - wordDict[i].size(),wordDict[i].size()) == wordDict[i]) || dp[j];

            }
        }

        // for(int i = 0; i < wordDict.size();i++)
        // {
        //     for(int j = 0; j < s.size();j++)
        //         cout << tmp[i][j] << ' ';
        //     cout << endl;
        // }
        
        return dp[s.size() ];
    }
};

2 多重背包

感觉考的不多,算法笔记也没有,看看理论

有N种物品和一个容量为V 的背包。第i种物品最多有Mi件可用,每件耗费的空间是Ci ,价值是Wi 。求解将哪些物品装入背包可使这些物品的耗费的空间 总和不超过背包容量,且价值总和最大。

解法1:每件物品最多有Mi件可用,把Mi件摊开,其实就是一个01背包问题了。

解法2:解法1上优化(神奇优化方式–二进制+拆包(具体过程见笔记本))

3 背包总结

from

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值