【算法练习Day39】单词拆分多重背包的介绍

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 单词拆分
  • 多重背包
  • 总结:

这一期到了背包问题的最后一期,主要讲解一道leetcodee题,和对多重背包的一些简单介绍,由于leetcode没有对于多重背包的具体问题,且面试基本不会问到多重背包所以只是作为科普。

单词拆分

139. 单词拆分 - 力扣(LeetCode)

给定一个字符串要求将其拆分,拆分后的各部分单词都可以在给我们的字符串字典里找到,也就是说该字符串是由该字符串字典的某些单词拼接而成。字符串字典里每个单词都可以重复使用。

这道题是分割字符串问题,也可以用回溯算法来求解。这里不做这方面的解析

无论是回溯算法还是完全背包的模型解决问题,都涉及到一个很重要的问题,如果不能想通,则问题将无法得到解决,我们在下面分析时候再做详细讲解。

动规分析

dp数组的含义:dp【i】指的是对于该字符串截止到第i个字符是否能由字符串字典里的字符串组成,如果能则dp【i】=true,否则则为false。

递推公式:dp【i】是否为真主要由两部分推测得来,一部分是我们要判断的这个字符串中由i到j的这个字符串是否在字典里出现过,另一部分是我们要判断的这个字符串它的前面如果有字符串那么它前面的字符串也必须是true,也就是说也必须由字符串字典的某些字符串构成,满足两者关系同时存在时,才能判定从头到现在的位置,为true。这一点很重要无论是回溯算法,还是用动态规划都要想出来,否则题目无法解出。

dp数组的初始化:根据递推公式得,由于dp【i】的推理依赖于前一个状态,所以dp【0】必须要初始化为true,否则最后不可能为true,其余的部分初始化为false即可。

遍历顺序:完全背包中的遍历顺序大多数都有考究的,不像01背包的一维数组实现,基本都是一样的遍历方法。这道题从排列组合的角度上思考,是要依靠排列的思想来写代码遍历,因为我们字符串字典里的字符串组成给定的字符串,是一定要有顺序的,顺序不对是无法拼接的。所以是先遍历背包再遍历物品。从直接看先遍历背包还是物品的角度来讲,如果先遍历物品再遍历背包,那么物品从前向后遍历只能遍历一次,无法达到物品可以重复使用的效果!这样推算下来肯定是有错误的,所以要先遍历背包。

class Solution {
public:bool wordBreak(string s, vector<string>& wordDict) {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);if(wordset.find(word)!=wordset.end()&&dp[j]==true)dp[i]=true;}   }return dp[s.size()];}
};

多重背包

多重背包是和01背包有相像之处的模型。给我们的物品,价值不同且每件物品都有有限个,也就是说物品件数不一定是1,但也不是无限的,可能是2,3,4个,求怎样装使背包容量之内获得价值最高。那么为什么说它和01背包有相似之处呢?这是由于我们可以将物品个数大于1的物品展开,比如有一物品价值15有两个,我们可以展开为价值15有一个,和价值15有一个。这样不就展开为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;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();
}

如果不展开物品的话,还有另一种方法。就是在背包里重复遍历该物品。

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();
}

我认为还是第一种方法比较好理解,对于第二种方法的递推公式,理解上可能有一点麻烦。

总结:

今天我们完成了单词拆分这道题,了解了多重背包的介绍,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【iOS】知乎日报前三周总结

这几天一直在进行知乎日报的仿写&#xff0c;仿写过程中积累了许多实用的开发经验&#xff0c;并对MVC有了更深的了解&#xff0c;特撰此篇作以总结 目录 第一周将网络请求封装在一个单例类Manager中SDWebImage库的简单使用运用时间戳处理当前时间自定义NavigationBar 第二周在…

轻量封装WebGPU渲染系统示例<12>- 基础3D对象实体(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/main/src/voxgpu/sample/PrimitiveEntityTest.ts 此示例渲染系统实现的特性: 1. 用户态与系统态隔离。 细节请见&#xff1a;引擎系统设计思路 - 用户态与系统态隔离-CSDN博客 2. 高频调用与低频调用隔…

基于STM32设计的室内环境监测系统(华为云IOT)_2023

一、设计需求 基于STM32+华为云物联网平台设计一个室内环境监测系统,以STM32系列单片机为主控器件,采集室内温湿度、空气质量、光照强度等环境参数,将采集的数据结果在本地通过LCD屏幕显示,同时上传到华为云平台并将上传的数据在Android移动端能够实时显示、查看。 【1…

小程序制作(超详解!!!)第十二节 循环求和计算器

1.index.wxml <view class"box"><view class"title">利用循环语句求和</view><view><input placeholder"请输入起点数值" type"number" bindblur"starNum"></input><!--一旦失去交…

个人服务器到期,项目下线,新的开始

告别旧服务器 2023.11.06服务器到期&#xff0c;所有项目正式下线 时间真的过的很快&#xff0c;从开始踏入编程的大门&#xff0c;到现在不知不觉已经陆续经手了两台服务器了&#xff0c;目前这台服务器是一年前的阿里云活动白嫖的嘿嘿嘿&#xff0c;该服务器上目前运行的项…

C++初阶-类和对象(中)2

类和对象&#xff08;中&#xff09;2 一、赋值运算符重载运算符重载赋值运算符重载前置和后置重载 二、日期类的实现三、const成员四、取地址及const取地址操作符重载 一、赋值运算符重载 运算符重载 C为了增强代码的可读性引入了运算符重载&#xff0c;运算符重载是具有特殊…

python 机器学习 常用函数

一 np.random.randint "randint" 是 "random integer" 的缩写&#xff0c;表示生成随机整数。 np.random.randint 是 NumPy 库中的一个函数&#xff0c;用于生成随机整数。以下是该函数的一般语法&#xff1a; np.random.randint(low, high, size)其中…

开发一款直播弹幕游戏需要多少钱?

开发一款直播弹幕游戏需要多少钱&#xff1f;有好多朋友在咨询过弹幕游戏的开发价格后&#xff0c;都会比较吃惊&#xff0c;一款体量这么小的游戏为什么动辄就要几万块甚至十几万&#xff1f; 我来给你们说分析一下原因&#xff0c;这种游戏如果脱离开直播间&#xff0c;可以…

MQTT协议零基础快速入门

MQTT协议零基础快速入门 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅消息传输协议&#xff0c;广泛应用于物联网&#xff08;IoT&#xff09;和机器对机器&#xff08;M2M&#xff09;通信场景。它具有简单、开放、易于实现等优…

Qt登录界面

头文件&#xff1a; #ifndef QDLGLOGIN_H #define QDLGLOGIN_H#include <QDialog>namespace Ui { class dlgLogin; }class QDlgLogin : public QDialog {Q_OBJECTprivate:bool m_movingfalse;//表示窗口是否在鼠标操作下移动QPoint m_lastPos; //上一次的鼠标位置Q…

MySQL进阶_5.逻辑架构和SQL执行流程

文章目录 第一节、逻辑架构剖析1.1、服务器处理客户端请求1.2、Connectors1.3、第1层&#xff1a;连接层1.4、第2层&#xff1a;服务层1.5、 第3层&#xff1a;引擎层1.6、 存储层1.7、小结 第二节、SQL执行流程2.1、查询缓存2.2、解析器2.3、优化器2.4、执行器 第三节、数据库…

GNU ld链接器 lang_process()(二)

一、ldemul_create_output_section_statements() 位于lang_process()中11行 。 该函数用于创建与目标有关的输出段的语句。这些语句将用于描述输出段的属性和分配。 void ldemul_create_output_section_statements (void) {if (ld_emulation->create_output_section_sta…