#139 单词拆分

没做出来。我原来是把string放到dp里,不对,这种做法永远都不对。他问的是什么(能不能构成,true,false)就要放到dp里 (大部分题是这样)下面是不对的思路:

正确code:

遍历物品有点特别:算是每个背包容量下,所有可能的 && 出现在wordset中的 substr

 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); //substr(起始位置,截取的个数)if (wordSet.find(word) != wordSet.end() && dp[j]) {dp[i] = true;}}}return dp[s.size()];}

# 多重背包

摊开之后变成:

void test_multi_pack() {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) { // nums[i]保留到1,把其他物品都展开weight.push_back(weight[i]);value.push_back(value[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]);}for (int j = 0; j <= bagWeight; j++) {cout << dp[j] << " ";}cout << endl;}cout << dp[bagWeight] << endl;}
int main() {test_multi_pack();
}

关键是这小段:

for (int i = 0; i < nums.size(); i++) {
        while (nums[i] > 1) { // nums[i]保留到1,把其他物品都展开
            weight.push_back(weight[i]);
            value.push_back(value[i]);
            nums[i]--;
        }
    }

随想录方法二:也有另一种实现方式,就是把每种商品遍历的个数放在01背包里面在遍历一遍。

void test_multi_pack() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};vector<int> nums = {2, 3, 2};int bagWeight = 10;vector<int> dp(bagWeight + 1, 0);for(int i = 0; i < weight.size(); i++) { // 遍历物品for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量// 以上为01背包,然后加一个遍历个数for (int k = 1; k <= nums[i] && (j - k * weight[i]) >= 0; k++) { // 遍历个数dp[j] = max(dp[j], dp[j - k * weight[i]] + k * value[i]);}}// 打印一下dp数组for (int j = 0; j <= bagWeight; j++) {cout << dp[j] << " ";}cout << endl;}cout << dp[bagWeight] << endl;
}
int main() {test_multi_pack();
}

# 背包总结:这里借鉴参考随想录的内容,自己修改了下:

I. 背包递推公式分类:

 1 问背包装满最大价值:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); 本公式是最基础版,是每个物品weight(加入限制)和value(我们要求的值)是分开的

  • 动态规划:474.一和零

474是普通完全背包,但是背包容量有两个维度,叠加两个一维完全背包成二维即可

2 问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]); ,其实和1 本质是一样的,不过每个物品 value和 weight是一个值

  • 动态规划:416.分割等和子集
  • 动态规划:1049.最后一块石头的重量 II

这俩题都是先数学稍微转换下成普通01背包。能否装满就查dp[ ]最后一个 == target

3 问装满背包有几种方法:dp[j] += dp[j - nums[i]]

  • 动态规划:494.目标和
  • 动态规划:518. 零钱兑换 II
  • 动态规划:377.组合总和Ⅳ
  • 动态规划:70. 爬楼梯进阶版(完全背包)

494(01), 518(完全),70(完全),基础款求多少种方法,70求排列,其他求组合

377(完全),求方法数,但是是 排列(背包容量外层),还要处理个溢出

完全背包是分排列和组合的,但我暂时感觉01背包只有组合,没有排列(不确定,也没想通为啥

4 问装满背包所有物品的最小个数:dp[j] = min(dp[j - coins[i]] + 1, dp[j]); ,这种题是排列还是组合无所谓,反正是求个数:

  • 动态规划:322.零钱兑换
  • 动态规划:279.完全平方数

比较特殊的题 139,dp里面放true false。139.单词拆分

if (wordSet.find(s.substr(j, i - j)) != wordSet.end() && dp[j]) {dp[i] = true;}

II. 遍历顺序:

我在完全背包的博客讲的很多的,这里就不写了。

代码随想录算法训练营第46天 | 动态规划 part08 ● 139.单词拆分 ● 关于多重背包 ● 背包问题总结篇相关推荐

  1. 代码随想录算法训练营第五十天|动态规划:139.单词拆分、多重背包理论基础、背包问题总结

    [139.单词拆分] 这个题目是一个背包问题.但是他稍微有点不太一样.在于这题判断能否装满背包是在判断单词是否出现在字典中,如果出现,就代表能装满. 背包是长度为i的字符串 物品是长度为i-j的子串 ...

  2. _42LeetCode代码随想录算法训练营第四十二天-动态规划 | 121.买卖股票的最佳时机、122.买卖股票的最佳时机II

    _42LeetCode代码随想录算法训练营第四十二天-动态规划 | 121.买卖股票的最佳时机.122.买卖股票的最佳时机II 题目列表 121.买卖股票的最佳时机 122.买卖股票的最佳时机II 1 ...

  3. 代码随想录算法训练营第四十六天|139.单词拆分、多重背包、背包问题总结篇

    一·.单词划分 给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词. 分析如下: 动规五部曲分析如下: 1.确定dp数组以及 ...

  4. 代码随想录算法训练营第42天 | 动态规划 part04 ● 背包问题二维● 背包问题滚动数组 一维 ● 416. 分割等和子集

    # 二维dp数组,01背包 1.确定dp数组以及下标的含义 dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少. 2.  gpt 解决我的困惑 3.  另外 ...

  5. 代码随想录算法训练营第四十二天-动态规划4|● 01背包问题,你该了解这些! ● 01背包问题,你该了解这些! 滚动数组 ● 416. 分割等和子集

    今天只有1道题,属于动态规划的01背包问题的应用.首先理解一下动态规划的01背包问题.推荐一个视频,动态规划DP0-1背包,这是我认为讲得最为通透的.很多讲解动态背包问题的,一上来就画二维表格,遍历背 ...

  6. 代码随想录算法训练营第45天动态规划 背包基础 1 2、 416. 分割等和子集

    文章目录 01背包基础 (二维数组) 思路 递推公式 初始化 遍历顺序 一维dp数组(滚动数组) 一维数组的递推公式 遍历顺序 LeetCode 416. 分割等和子集 思路 总结 01背包基础 (二 ...

  7. _28LeetCode代码随想录算法训练营第二十八天-贪心算法 | 122.买卖股票的最佳时机II 、55.跳跃游戏、45.跳跃游戏II

    _28LeetCode代码随想录算法训练营第二十八天-贪心算法 | 122.买卖股票的最佳时机II .55.跳跃游戏.45.跳跃游戏II 题目列表 122.买卖股票的最佳时机II 55.跳跃游戏 45 ...

  8. _32LeetCode代码随想录算法训练营第三十二天-贪心算法 | 738.单调递增的数字 、714.买卖股票的最佳时机含手续费、968.监控二叉树

    _32LeetCode代码随想录算法训练营第三十二天-贪心算法 | 738.单调递增的数字 .714.买卖股票的最佳时机含手续费.968.监控二叉树 题目列表 738.单调递增的数字 714.买卖股票 ...

  9. 代码随想录算法训练营day42 | 01背包问题,你该了解这些!,01背包问题,你该了解这些! 滚动数组 , 416. 分割等和子集

    代码随想录算法训练营day42 | 背包理论基础,背包理论基础(滚动数组), 416. 分割等和子集 1.01背包理论基础 背包问题概述 01背包 二维dp数组01背包案例 2.01背包理论基础(滚动 ...

最新文章

  1. python 实现桶排序
  2. 系统集成项目管理工程师软考辅导——3年真题透解与全真模拟
  3. JavaScript中避免Form重复提交的两种方案
  4. python登录接口代码_(转载)Python 的 OAuth 登录接口 python-oauth2
  5. mysql insert执行过程_MySQL · 源码分析 · 一条insert语句的执行过程
  6. 安装cadence ic5141时碰到字体问题
  7. auto与迭代器的用法_C++ STL move_iterator移动迭代器用法详解
  8. Android 开源框架Universal-Image-Loader学习
  9. A饭福利,AMD Mantle API获众多游戏开发商青睐!
  10. [Unity]限制两个物体之间的距离
  11. BugkuCTF-MISC题convert
  12. Spring:自动装配模式
  13. ASP.NET Web开发框架之八 所有ERP部分的源代码全部开放下载
  14. php 可选表格,PHP_表格标记,  ■ 表格标记 TABLE - phpStudy
  15. 配置 .vimrc 解决 Vim / gVim 在中文 Windows 下的字符编码问题
  16. 晶振PCB layout注意事项
  17. php密钥,php – 唯一的密钥生成
  18. Android 初学者入门(一个最简单的应用程序)
  19. 长尾理论读书笔记:第一章 长尾市场
  20. mac系统下word和excel设置文件打开密码,输入密码才能打开文件

热门文章

  1. ZStack搭建私有云,创建windows server 2008云主机
  2. python语言的单行注释以井号开头_python001 -- 简要介绍
  3. Centos 建立一个新用户 详细讲解
  4. matlab高斯白噪声功率,自定义高斯白噪声功率和带宽
  5. 靶中化合物设计/靶点及信号通路验证之酶抑制剂靶点预测
  6. c语言负数左移右移_C语言里的左移和右移运算
  7. 2023,分析一下Python的前景
  8. ASOP源码中单独编译preloader/lk/kernel/framework模块
  9. git clone error 10054
  10. Raspbian中搭建Home Assistant并接入rtsp摄像头