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

news2024/12/23 19:49:27

在这里插入图片描述

​📝个人主页:@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.coloradmin.cn/o/1174392.html

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

相关文章

[BUUCTF NewStar 2023] week5 Crypto/pwn

最后一周几个有难度的题 Crypto last_signin 也是个板子题&#xff0c;不过有些人存的板子没到&#xff0c;所以感觉有难度&#xff0c;毕竟这板子也不是咱自己能写出来的。 给了部分p, p是1024位给了922-101位差两头。 from Crypto.Util.number import * flag b?e 655…

Winform 实现俄罗斯方块游戏(一)

第一步&#xff0c;先用GDI绘制小正方形方块&#xff0c;其它形状的用这个方块合成 如何绘制一个方块&#xff1f;先绘制两个正方形&#xff0c;如下&#xff1a; 然后四周用梯形填充&#xff0c;内部颜色用渐变&#xff0c;这样更有立体感&#xff0c;下篇介绍如何实现。

D-link未授权访问以及远程代码执行

随便输入一个错误密码&#xff0c;会跳转到页面&#xff1a; /page/login/login.html?errorfail继续访问有效页面漏洞url&#xff1a; /Admin.shtml然后访问管理页面去更改管理密码 直接构造payload访问漏洞url&#xff1a; /cgi-bin/execute_cmd.cgi?cmdid执行命令&#…

2023年11月5日网规考试备忘

早上题目回忆&#xff1a; pki体系 ipsec&#xff0c;交换安全&#xff08;流量抑制&#xff09; aohdlc bob metclaf —ethernet pon tcp三次握手 OSPF lsa&#xff1f;交换机组ospf配置问题&#xff0c;ping网关可通&#xff0c;AB不通 raid6 300G*8 网络利用率 停等协议10…

腾讯云CVM S5服务器4核8G配置性能测评和优惠价格表

腾讯云4核8G服务器CVM标准型S5实例性能测评&#xff0c;包括CPU型号、内存、系统盘、CVM实例规格性能测评&#xff0c;腾讯云4核8G租用优惠价格表&#xff0c;腾讯云服务器网txyfwq.com分享腾讯云4核8G服务器CVM S5性能测评和优惠价格表&#xff1a; 腾讯云4核8G服务器CVM S5性…

dupeGuru 清理微信重复文件

本文摘录于&#xff1a;https://www.bilibili.com/video/BV13p4y1G75Y/?spm_id_from333.337.search-card.all.click&vd_source483e5c52353ea59d1a5eadac7737591a只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 微信用了七八年,文件…

Java异常你还没有了解吗?

&#x1f937;‍♀️&#x1f937;‍♀️&#x1f937;‍♀️ 今天和大家一起学习一下Java中的异常&#xff01; 清风的CSDN博客个人主页 &#x1f302;c/java领域新星创作者 &#x1f389;欢迎&#x1f44d;点赞✍评论❤️收藏 &#x1f61b;&#x1f61b;&#x1f61b;希望我…

【JavaScript】window 对象、location 对象、navigator 对象和 history 对象

1. window 对象 BOM (Browser Object Model ) 是浏览器对象模型&#xff1a; window对象是一个全局对象&#xff0c;也可以说是JavaScript中的顶级对象像document、alert()、console.log()这些都是window的属性&#xff0c;基本BOM的属性和方法都是window的所有通过var定义在全…

【Java 进阶篇】JSP 简单入门

在现代Web开发中&#xff0c;JavaServer Pages&#xff08;JSP&#xff09;是一项非常重要的技术。JSP允许开发者将Java代码嵌入HTML页面&#xff0c;以实现动态内容的生成和呈现。本文将详细介绍JSP的概念、原理以及如何使用JSP来构建Web应用程序。 第一部分&#xff1a;JSP …

基于Google Colaboratory安装Go语言编译器操作流程

文章目录 1. 什么是Google Colaboratory2. 访问Google Colaboratory3. 创建新的笔记本4.【方法①】使用apt命令安装golang5.【方法②】使用Go安装包安装golang6. 参考链接 1. 什么是Google Colaboratory Colab是一种托管的笔记本电脑服务&#xff0c;不需要安装即可使用&#x…

Perl安装教程

1. perl简介 Perl 是 Practical Extraction and Report Language 的缩写&#xff0c;可翻译为 “实用报表提取语言”。Perl 是高级、通用、直译式、动态的程序语言。Perl 最初的设计者为拉里沃尔&#xff08;Larry Wall&#xff09;&#xff0c;于1987年12月18日发表。Perl 借…

PCTA认证考试-01_TiDB数据库架构概述

TiDB 数据库架构概述 一、学习目标 理解 TiDB 数据库整体结构。了解 TiDB Server&#xff0c;TiKV&#xff0c;TiFlash 和 PD 的主要功能。 二、TiDB 体系架构 1. TiDB Server 2. TiKV OLTP 3. Placement Driver 4. TiFlash OLAP OLTPOLAPHTAP

【Go 编程实践】从零到一:创建、测试并发布自己的 Go 库

为什么需要开发自己的 Go 库 在编程语言中&#xff0c;包&#xff08;Package&#xff09;和库&#xff08;Library&#xff09;是代码组织和复用的重要工具。在 Go 中&#xff0c;包是代码的基本组织单位&#xff0c;每个 Go 程序都由包构成。包的作用是帮助组织代码&#xf…

高等数学教材重难点题型总结(十二)无穷级数

最后一更&#xff01;原谅博主已经开始瞎写字了&#xff0c;最近压力太大&#xff0c;以后有时间用mathPix打出来&#xff0c;看起来更舒适一些~ 高数最后一章&#xff0c;重点在于审敛法和求解幂级数的收敛半径~ 高数基础笔记全部更新完毕&#xff0c;共12*336期&#xff0c…

【qemu逃逸】华为云2021-qemu_zzz

前言 虚拟机用户名&#xff1a;root 无密码 设备逆向 经过逆向分析&#xff0c;可得实例结构体大致结构如下&#xff1a; 其中 self 指向的是结构体本身&#xff0c;cpu_physical_memory_rw 就是这个函数的函数指针。arr 应该是 PCI 设备类结构体没啥用&#xff0c;就直接用…

动态规划算法实现0-1背包问题Java语言实现

问题介绍&#xff1a; 动态规划算法&#xff1a; 动态规划&#xff08;Dynamic Programming&#xff09;是一种解决多阶段决策问题的优化算法。它通过将问题分解为一系列子问题&#xff0c;并利用子问题的解来构建更大规模问题的解&#xff0c;从而实现对整个问题的求解。 动态…

五子棋对战测试报告

目录 一、项目背景 二、项目功能 三、功能测试 1、注册页面测试 测试用例 测试结果 测试总结 2、登录页面测试 测试用例 测试结果 测试总结 3、游戏大厅页面测试 测试用例 测试结果 测试总结 4、游戏房间页面测试 测试用例 测试结果 测试总结 一、项目背景 …

物联网AI MicroPython传感器学习 之 无源蜂鸣器

一、产品简介 蜂鸣器是一种将音频信号转化为声音信号的发音器件传感器&#xff0c;通过利用压电效应原理&#xff0c;当对其施加交变电压时产生机械振动。应用场景&#xff1a;在家用电器、电子玩具、游戏机等场景下都得到普遍应用&#xff0c;通过设置不同的频率&#xff0c;…

Linux下yum源配置实战

一、Linux下软件包的管理 1、软件安装方式 ① RPM包管理&#xff08;需要单独解决依赖问题&#xff09; ② YUM包管理&#xff08;需要有网络及YUM仓库的支持&#xff0c;会自动从互联网下载软件&#xff0c;自动解决依赖&#xff09; ③ 源码安装&#xff08;安装过程比较…

前端面试题之CSS篇

1、css选择器及其优先级 标签选择器: 1类选择器、属性选择器、伪类选择器&#xff1a;10id选择器&#xff1a;100内联选择器&#xff08;style“”&#xff09;&#xff1a;1000!important&#xff1a;10000 2、display的属性值及其作用 属性值作用none元素不显示&#xff0c…