139.单词拆分 多重背包理论 打家劫舍 I II III

news2025/2/28 17:02:58

139.单词拆分

题目

给一个非空字符串s,和一个非空单词集 wordDict,判断可不可以用空格把s分为wordDict里的一个或多个单词(必须全部拆成单词才返回ture)。

(可以重复拆分为单词集的同个单词,默认单词集没有重复的)

思路:

字符串s比作背包,单词比作物品,单词能否组成字符串s,就是问物品能不能把背包装满。

单词可以重复拆分(使用),表示是完全背包。

dp[i]含义:

dp[i]表示字符串长度为i的时候可以用空格拆分成单词集的一个或多个单词

递推公式:

dp[i]的状态可以由dp[j](j<i)和 在 j - i 之间的字符串是否能被用空格拆分成单词集的一个或多个单词的状态推出来,如果dp[j](j<i)为ture,同时 j - i 也为ture(能被拆分),那么可以推出dp[i]为ture。(这里满足条件就ture)

                string word = s.substr(j, i - j); //substr(起始位置,截取的个数)
                if (wordSet.find(word) != wordSet.end() && dp[j]) {
                    dp[i] = true;

初始化:

dp[0]=ture,dp[0]是推导的根基,如果dp[0]是false,那么两个条件判断就没法推导下去了,

dp[除了0之外的]都初始为false,如果满足条件了,会被覆盖成ture

遍历顺序:

求的是排列数,先背包后物品,比如字符串s是applepen,apple+pen和pen+apple,只有apple+pen 是符合的,只有apple+pen才能变成applepen

总代码

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

多重背包理论

多重背包也是一种01背包,在01背包问题的基础上,每种物品有多件可以用,把多件同一物体摊开成多个物体就是多重背包。

多重背包: 

重量价值数量
物品01152
物品13203
物品24302

 摊开成01背包:

重量价值数量
物品01151
物品01151
物品13201
物品13201
物品13201
物品24301
物品24301

 代码按01背包写,在01背包的基础上“摊开”,插入多个同级物品或者直接加一层for循环遍历个数

代码这里,代码随想录

背包问题总结

01背包

物品只能放一次或者不放就是01背包。

递推公式:

问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);

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

问背包装满最大价值:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

问装满背包所有物品的最小个数:dp[j] = min(dp[j - coins[i]] + 1, dp[j]); 

遍历顺序:

二维数组的01背包,先遍历物品或背包都可以,遍历顺序大到小,小到大遍历都可以

一维数组的01背包,只能先遍历物品再遍历背包,背包遍历需要从大到小。

完全背包

物品可以放无数个就是完全背包

遍历顺序:

纯完全背包问题,先遍历背包或物品都可以,同时第二层for循环必须由小到大

但是去区分,是求背包问题的组合还是排列数,组合先物品后背包,排列数先背包后物品。(同时第二层for循环需要从小到大)

如果求最小数无所谓物品背包的先后顺序

多重背包

01背包的物品加上个数就是多重背包,把01背包的代码,把个数变成对应的物品插入进去或者加一层for循环遍历就是多重背包的解决代码。

打家劫舍 I

题目:

给一个金额数组,元素值是正整数,每一个都可以被获取,但如果一个元素被获取了,那相邻的数组元素就不能被获取,求能获得的金额最大值

dp[i]含义:

dp[i]的意思就是,下标为i的数组能获取到的金额最大值dp[i]

递推公式:

dp[i]可以由偷不偷第i间房间的来,偷的话,dp[i]=dp[i-2]+num[i],意为 i-1 间不偷,i-2间偷加上i间偷。另外一个就是i间不偷,考虑i-1间偷不偷。(会有偷了比不偷好的,比如1 1 1 1 100 1 1 1)

dp[i]取最大值,即dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);(考虑下标i以及下标i之前能取到的最大值)

初始化:

由题目可知 dp[0]=num[0] ,dp[1]=max(num[0],num[1])

遍历顺序:

dp[i]由dp[i-2]和dp[i-1]推出来,所以由前向后遍历。

总代码

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 0) return 0;
        if (nums.size() == 1) return nums[0];
        vector<int> dp(nums.size());
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 2; i < nums.size(); i++) {
            dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        return dp[nums.size() - 1];
    }
};

打家劫舍 II

题目:

给一个环形的金额数组,首位是相互连接的,元素值是正整数,每一个都可以被获取,但如果一个元素被获取了,那相邻的数组元素就不能被获取,求能获得的金额最大值

思路:

因为首尾相连,数组头部尾部不能一起取,可以拆成3种可能的数组,考虑取头或取尾,或者考虑两个都不取,每一种可能的数组分离出来,由之前打劫1的代码去套,综合起来取最大值就好。

总代码:

这里考虑头尾都不取 被 考虑取头和考虑取尾的考虑范围覆盖了(包含头尾都不取的考虑范围)

// 注意注释中的情况二情况三,以及把198.打家劫舍的代码抽离出来了
class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 0) return 0;
        if (nums.size() == 1) return nums[0];
        int result1 = robRange(nums, 0, nums.size() - 2); // 考虑取头
        int result2 = robRange(nums, 1, nums.size() - 1); // 考虑取尾
        return max(result1, result2);
    }
    // 198.打家劫舍的逻辑
    int robRange(vector<int>& nums, int start, int end) {
        if (end == start) return nums[start];
        vector<int> dp(nums.size());
        dp[start] = nums[start];//这里start是因为考虑数组
        dp[start + 1] = max(nums[start], nums[start + 1]);
        for (int i = start + 2; i <= end; i++) {
            dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        return dp[end];
    }
};

打家劫舍 III

题目:

给一个二叉树,二叉树里面是金额的值(正整数),每一个节点的值都可以被获取,但是如果一个节点被获取了值,那它连接的其他节点不能被获取,求能获取金额的最大值。

思路:

用二叉树后续遍历,左右中,遍历左节点的同时遍历右节点,不断的求两个节点的可能最大值,然后到达根节点,继续判断取根据点大还是不取根节点大,然后对比最大值得出结果。

每个过程他是怎么求最大值的?

在后续遍历的基础上,用dp数组来代表偷和不偷得到的最大金额,每一次回溯都会向上传递这一层偷与不偷的最大值,到最后左节点偷的最大值,左节点不偷的最大值,右节点偷的最大值,右节点不偷的最大值都完成了,到了根节点再判断,偷根节点的值最大还是不偷根节点的值最大,比如示例{6,7},

不偷,就是其左节点不偷的最大值3+其右节点不偷的最大值3 = 6

偷,就是根节点的值3+他左孩子的孩子节点的偷最大值3+他右​​​​​​​孩子的孩子节点的偷最大值1 = 7

然后对比取最大值得到最大金额。

dp数组(dp table)以及下标的含义:

下标为0记录不偷该节点所得到的的最大金钱,下标为1记录偷该节点所得到的的最大金钱。

遍历示例图和讲解:空降16.20

总代码:

class Solution {
public:
    int rob(TreeNode* root) {
        vector<int> result = robTree(root);
        return max(result[0], result[1]);
    }
    // 长度为2的数组,0:不偷,1:偷
    vector<int> robTree(TreeNode* cur) {
        if (cur == NULL) return vector<int>{0, 0};
        vector<int> left = robTree(cur->left);
        vector<int> right = robTree(cur->right);
        // 偷cur,那么就不能偷左右节点。
        int val1 = cur->val + left[0] + right[0];
        // 不偷cur,那么可以偷也可以不偷左右节点,则取较大的情况
        int val2 = max(left[0], left[1]) + max(right[0], right[1]);
        return {val2, val1};
    }
};

nb 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1158190.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

天线测试解决方案-毫米波片上天线测量系统

毫米波片上天线测量系统 方案概述&#xff1a; 毫米波片上天线测量系统频率范围覆盖8GHz&#xff5e;110GHz&#xff08;可扩展至500GHz&#xff09;&#xff0c;具有频率覆盖范围宽、动态范围大、馈电形式灵活、结构紧凑、测试参数全面等特点。系统采用通用化、模块化设计思想…

设计模式(23)解释器模式

一、介绍&#xff1a; 1、定义&#xff1a;解释器(Interpreter)模式是一种对象的行为模式。给定一个语言&#xff0c;定义它的文法的一种表示&#xff0c;并定义一个解释器&#xff0c;这个解释器使用该表示来解释语言中的句子。 2、组成结构&#xff1a; &#xff08;1&…

SaaS 出海,如何搭建国际化服务体系?(二)

防噎指南&#xff1a;这可能是你看到的干货含量最高的 SaaS 出海经验分享&#xff0c;请准备好水杯&#xff0c;放肆食用&#xff08;XD。 当越来越多中国 SaaS 企业选择开启「国际化」副本&#xff0c;出海便俨然成为国内 SaaS 的新角斗场。 LigaAI 观察到&#xff0c;出海浪…

企业工程项目管理系统源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)==

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&am…

html用css grid实现自适应四宫格放视频

想同时播放四个本地视频&#xff1a; 四宫格&#xff1b;自式应&#xff0c;即放缩浏览器时&#xff0c;四宫格也跟着放缩&#xff1b;尽量填满页面&#xff08;F11 浏览器全屏时可以填满整个屏幕&#xff09;。 在 html 中放视频用 video 标签&#xff0c;参考 [1]&#xff1…

linux的环境安装以及部署前后端分离后台接口

⭐⭐ linux专栏&#xff1a;linux专栏 ⭐⭐ 个人主页&#xff1a;个人主页 目录 一.linux安装环境 1.1 jdk和tomcat的安装配置 1.1.1 解压jdk和tomcat的安装包 解压jdk安装包 解压tomcat安装包 1.2 jdk环境变量配置 1.3 tomcat启动 1.4 MySQL的安装 二.部署前后端分离…

多通道振弦数据记录仪在铁路隧道监测中的重要应用

多通道振弦数据记录仪在铁路隧道监测中的重要应用 岩土工程监测是工程建设中不可或缺的一环&#xff0c;特别是在铁路隧道工程中更是如此。为此&#xff0c;振弦数据记录仪成为了一种非常重要的仪器&#xff0c;可以帮助监测人员实时监测隧道内部的变化&#xff0c;为工程的安…

通付盾Web3专题 | 智能账户:数字时代基础单元

2008年10月31日&#xff0c;中本聪&#xff08;Satoshi Nakamoto&#xff09;在P2P foundation 网站发布比特币白皮书《比特币&#xff1a;一种点对点的电子现金系统》。转眼距比特币白皮书发布已过去15年。2009年1月比特币网络正式推出&#xff0c;当时每个比特币的价格仅为0.…

科研迷雾:读研以来,我发现的科研界“怪象”

1 引言 随着读论文和做实验的增多&#xff0c;我发现了sci的很多猫腻经不起细细推敲&#xff0c;原来科研并不如我想象的神圣&#xff0c;还不如工业界来的实在&#xff0c;因为在工业界做项目出现问题&#xff0c;客户是验收不了不给付钱的。所以论文只是一个玩具。 2 常见的…

diffusers-Load adapters

https://huggingface.co/docs/diffusers/main/en/using-diffusers/loading_adaptershttps://huggingface.co/docs/diffusers/main/en/using-diffusers/loading_adapters 有几种训练技术可以个性化扩散模型&#xff0c;生成特定主题的图像或某些风格的图像。每种训练方法都会产…

2015年美亚杯全国电子数据取证大赛个人

做题 1.请找出如下windows XP系统信息&#xff1a;&#xff08;10分&#xff09; a. 系统安装时间 &#xff08;YYYY/MM/DD&#xff09; 考时间 我们先去看看该电脑的时区 都是东八区 那我们直接看时间 因为题目没有要求我们时间 答案为 2015-08-07 16:45:52 转为格式 201…

玻色量子签约移动云“五岳”量子云计算创新加速计划!

2023年4月24-26日&#xff0c;由中国移动通信集团主办的“云擎未来 智信天下”2023移动云大会在苏州圆满落幕。 中国移动在本次大会发布了“五岳”量子云计算创新加速计划。作为中国移动量子计算方向的战略伙伴&#xff0c;玻色量子创始人&CEO文凯博士代表北京玻色量子科技…

【快刊解读】2个月录用!3区SCIE,无需版面费,国人友好~

计算机领域 • 好刊解读 今天小编带来Springer旗下计算机领域好刊的解读&#xff0c;如有相关领域作者有意向投稿&#xff0c;可作为重点关注&#xff01;后文有同领域快刊发表案例&#xff0c;供您投稿参考~ 01 期刊简介 Journal of Network and Systems Management ☑️出…

HTML区块、布局

HTML区块&#xff1a; HTML可以通过<div> 和 <span>将元素组合起来。大多数HTML元素被定义为块级元素或内联元素。块级元素在浏览器显示时&#xff0c;通常会以新行来开始、结束&#xff1b;内联元素在显示时通常不会以新行开始。 HTML<div>元素是块级元素…

【韵律之声】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

想去银行的背完这些软件测试面试题,你就稳了...

前言 最近呢有很多的小伙伴问我有没有什么软件测试的面试题&#xff0c;由于我之前一直在忙工作上的事情&#xff0c;没有时间整理面试题&#xff0c;刚好最近休息了一下&#xff0c;顺便整理了一些面试题&#xff0c;现在就把整理的面试题分享给大家&#xff0c;废话就不多说…

怎样才知道一个单片机的性能到极限了?

怎样才知道一个单片机的性能到极限了&#xff1f; 就题主的问题&#xff0c;应该是想问CPU利用率的问题。可以看看Rt-thread中关于统计CPU利用率函数&#xff0c;其主要实现方式是在idle线程先关闭中断计数后&#xff0c;正常计数(可被其他线程打断)&#xff0c;最近很多小伙伴…

面试算法48:序列化和反序列化二叉树

题目 请设计一个算法将二叉树序列化成一个字符串&#xff0c;并能将该字符串反序列化出原来二叉树的算法。 分析 先考虑如何将二叉树序列化为一个字符串。需要逐个遍历二叉树的每个节点&#xff0c;每遍历到一个节点就将节点的值序列化到字符串中。以前序遍历的顺序遍历二叉…

IP地址管理系统phpipam部署

IP地址管理系统phpipam部署 一、IPAM管理系统简介二、IPAM安装部署教程2.1 环境准备 三、phpIPAM web配置3.1 初始化3.2 WEB配置使用 四、IPAM管理和使用4.1配置dns4.2 配置ip网段4.3 配置ip地址自动扫描 一、IPAM管理系统简介 phpipam是一个开源Web IP地址管理应用程序&#…

28岁学C+大家随便说点想法吧

28岁学C&#xff0c;大家随便说点想法吧&#xff0c;让我随便了解了解东西&#xff0c;劝退的也好。&#xff1f; 你这种情况可以学&#xff0c;可以带薪学习是很幸福的事情。 28岁如果才开始学C 等着学会了再找工作就是很难得事情了&#xff0c;相当于等米下锅、而稻种都还没…