Day46|动态规划part08:139.单词拆分、多重背包理论基础、背包问题总结

news2024/11/16 11:39:40

139. 单词拆分

leetcode链接:力扣题目链接

视频链接:你的背包如何装满?| LeetCode:139.单词拆分

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet""code" 拼接成。
示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
     注意,你可以重复使用字典中的单词。

示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

这题可以看成一个完全背包问题,其中字典是物品,目标字符串是背包,字典中的单词可以使用无数次。

  1. 确定dp数组及其含义

dp[j] 表示字符串长度为j时,都可以用字典中的词表示。

  1. 确定递推公式

如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。(j < i )。

所以递推公式是 if([j, i] 这个区间的子串出现在字典里 && dp[j]是true) 那么 dp[i] = true。

  1. dp数组的初始化

从递推公式中可以看出,dp[i] 的状态依靠 dp[j]是否为true,那么dp[0]就是递推的根基,dp[0]一定要为true,否则递推下去后面都都是false了。

dp[0] = true;其他的初始化为false;

  1. 确定遍历顺序

本题其实我们求的是排列数,为什么呢。 拿 s = “applepenapple”, wordDict = [“apple”, “pen”] 举例。

“apple”, “pen” 是物品,那么我们要求 物品的组合一定是 “apple” + “pen” + “apple” 才能组成 “applepenapple”。

“apple” + “apple” + “pen” 或者 “pen” + “apple” + “apple” 是不可以的,那么我们就是强调物品之间顺序。

所以说,本题一定是 先遍历 背包,再遍历物品。

  1. 循环打印dp数组

image

最终代码:

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

这里注意在vector中查找的元素的写法:

find(wordDict.begin(),wordDict.end(), s.substr(j,i - j)) != wordDict.end()

多重背包理论基础(了解,面试基本不考)

多重背包与01背包相比,没有只能用一件的限制,与完全背包相比,想用的物品又不是无限的。

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

多重背包和01背包是非常像的, 为什么和01背包像呢?

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

例如:

背包最大重量为10。

物品为:

Table

重量

价值

数量

物品0

1

15

2

物品1

3

20

3

物品2

4

30

2

问背包能背的物品最大价值是多少?

和如下情况有区别么?

Table

重量

价值

数量

物品0

1

15

1

物品0

1

15

1

物品1

3

20

1

物品1

3

20

1

物品1

3

20

1

物品2

4

30

1

物品2

4

30

1

毫无区别,这就转成了一个01背包问题了,且每个物品只用一次。

于是可以讲nums数组展开,再当成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();
}

也有另一种实现方式,就是把每种商品遍历的个数放在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();
}

多重背包在面试中基本不会出现,力扣上也没有对应的题目,大家对多重背包的掌握程度知道它是一种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背包问题,你该了解这些! (opens new window)中我们讲解二维dp数组01背包先遍历物品还是先遍历背包都是可以的,且第二层for循环是从小到大遍历。

和动态规划:关于01背包问题,你该了解这些!(滚动数组) (opens new window)中,我们讲解一维dp数组01背包只能先遍历物品再遍历背包容量,且第二层for循环是从大到小遍历。

一维dp数组的背包在遍历顺序上和二维dp数组实现的01背包其实是有很大差异的,大家需要注意!

完全背包

说完01背包,再看看完全背包。

在动态规划:关于完全背包,你该了解这些! (opens new window)中,讲解了纯完全背包的一维dp数组实现,先遍历物品还是先遍历背包都是可以的,且第二层for循环是从小到大遍历。

但是仅仅是纯完全背包的遍历顺序是这样的,题目稍有变化,两个for循环的先后顺序就不一样了。

如果求组合数就是外层for循环遍历物品,内层for遍历背包

如果求排列数就是外层for遍历背包,内层for循环遍历物品

如果求最小数,那么两层for循环的先后顺序就无所谓了。

总结:

[外链图片转存中…(img-uufr1YJr-1693016282307)]

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

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

相关文章

【Linux】目录结构、路径

目录 1. 目录结构 1.1 基本概念 1.2 具体的目录结构 2. 路径 2.1 绝对路径和相对路径 2.2 特殊路径符 1. 目录结构 1.1 基本概念 Linux的目录结构是一个树形结构。 Windows系统可以拥有多个盘符&#xff0c;如 C盘、D盘、E盘。Linux没有盘符这个概念&#xff0c;只有一…

树莓派自带的GPIO串口输出及输出乱码问题解决方案

可以使用树莓派的UART0进行串口输出&#xff0c;具体连接方法如图所示&#xff1a; 连接后可以使用如下代码发送串口数据&#xff1a; import serial import time# 串口初始化 ser serial.Serial(/dev/serial0, 9600, timeout1) # /dev/serial0 是树莓派上默认的串口设备# 发…

图书馆项目Java阅览室管理系统jsp源代码MySQL

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 图书馆项目 系统有1权限&#xff1a;管理员 用所技术…

Scikit-Learn中的特征选择和特征提取详解

概要 机器学习在现代技术中扮演着越来越重要的角色。不论是在商业界还是科学领域&#xff0c;机器学习都被广泛地应用。在机器学习的过程中&#xff0c;我们需要从原始数据中提取出有用的特征&#xff0c;以便训练出好的模型。但是&#xff0c;如何选择最佳的特征是一个关键问…

eslint和prettier格式化冲突

下载插件 ESLint 和 Prettier ESLint 进入setting.json中 setting.json中配置 {"editor.tabSize": 2,"editor.linkedEditing": true,"security.workspace.trust.untrustedFiles": "open","git.autofetch": true,"…

ARM开发,stm32mp157a-A7核(UART总线实验)

1.目标&#xff1a;键盘输入一个字符a,串口工具显示b&#xff1b; 键盘输入一个字符串"nihao",串口工具显示"nihao"&#xff1b; 2.框图分析&#xff1a; 3.代码&#xff1a; ---.h头文件--- #ifndef __UART4_H__ #define __UART4_H__#include "st…

1.Prometheus

文章目录 Prometheus概述存储特点生态组件Prometheus serverClient LibraryExportersService DiscoveryAlertmanagerPushgatewayGrafana 工作模式工作流程局限性 部署prometheus部署 Node Exporter部署mysqld_exporter部署nginx-exporter部署grafana 总结 Prometheus 概述 za…

Yolo系列-yolov1

YOLO-V1 经典的one-stage方法 YouOnlyLookOnce&#xff0c;名字就已经说明了一切&#xff01;把检测问题转化成回归问题&#xff0c;一个CNN就搞定了&#xff01;可以对视频进行实时检测&#xff0c;应用领域非常广&#xff01; 核心思想&#xff1a; Yolov1的核心思想是将对象…

Adapter Tuning Overview:在CV,NLP,多模态领域的代表性工作

文章目录 Delta TuningAdapter Tuning in CVAdapter Tuning in NLP Delta Tuning Adapter Tuning in CV 题目: Learning multiple visual domains with residual adapters 机构&#xff1a;牛津VGG组 论文: https://arxiv.org/pdf/1705.08045.pdf Adapter Tuning in NLP …

input输入框和按钮相关联

有了内容&#xff0c;提交按钮才会起作用&#xff01;&#xff01;&#xff01; 当input输入框中输入内容的时候&#xff0c;按钮从禁用状态变成可用状态&#xff01; 输入框中输入的内容会同步输出&#xff0c; 输入的内容被存放在e.detail.value中&#xff0c;将其提取出来赋…

MybatisPlus拦截器实战之数据的加解密和脱敏

文章目录 一、前言二、拦截器简介三、代码目录结构简介四、核心代码讲解4.1 application.yml文件4.2 自定义注解4.2.1 SensitiveEntity4.2.2 SensitiveData4.2.3 MaskedEntity4.2.4 MaskedField4.2.5 MaskedMethod 4.3 Mybatis-Plus 拦截器数据自动加密4.4 Mybatis 打印完整sql…

浅析Linux SCSI子系统:设备管理

文章目录 概述设备管理数据结构scsi_host_template&#xff1a;SCSI主机适配器模板scsi_host&#xff1a;SCSI主机适配器主机适配器支持DIF scsi_target&#xff1a;SCSI目标节点scsi_device&#xff1a;SCSI设备 添加主机适配器构建sysfs目录 添加SCSI设备挂载Lun 相关参考 概…

FTHR-G0001 新手小白的第一块keil开发板

前言 作为从未接触过这类板子的新手&#xff0c;从申请起就十分忐忑&#xff0c;拿到板子的第一印象就是小而又特别&#xff0c;既可以整块板使用&#xff0c;也可以掰开用杜邦线连接的形式具备了灵活与小巧的特点&#xff0c;而核心板的把排针围成一圈的设计就足以让它在树莓…

HRS--人力资源系统(Springboot+vue)--打基础升级--(五)编辑当条记录

今天开发第一步&#xff1a;当前条记录&#xff0c;点击编辑&#xff0c;可以修改数据 1. 首先点击编辑&#xff0c;获取到了当前条的数据&#xff0c;弹出了一个小窗口 这个窗口是不是很熟悉&#xff0c;&#xff0c;没错。。这个窗口跟新增按钮弹出的窗口是同一个的 bug1&am…

使用 Next.js、Langchain 和 OpenAI 构建 AI 聊天机器人

在当今时代&#xff0c;将 AI 体验集成到您的 Web 应用程序中变得越来越重要。LangChain 与 Next.js 的强大功能相结合&#xff0c;提供了一种无缝的方式来将 AI 驱动的功能引入您的应用程序。 在本指南中&#xff0c;我们将学习如何使用Next.js&#xff0c;LangChain&#xf…

【MongoDB系列】1.MongoDB 6.x 在 Windows 和 Linux 下的安装教程(详细)

本文主要介绍 MongoDB 最新版本 6.x 在Windows 和 Linux 操作系统下的安装方式&#xff0c;和过去 4.x 、5.x 有些许不同之处&#xff0c;供大家参考。 Windows 安装 进入官网下载 Mongodb 安装包&#xff0c;点此跳转&#xff0c;网站会自动检测当前操作系统提供最新的版本&…

线性代数的学习和整理14: 线性方程组求解

目录 1 线性方程组 2 有解&#xff0c;无解 3 解的个数 1 线性方程组 A*xy 3根直线的交点&#xff0c;就是解 无解的情况 无解&#xff1a; 三线平行无解&#xff1a;三线不相交 有解 有唯一解&#xff1a;三线相交于一点有无数解&#xff1a;三条线重叠 2 齐次线性方程组…

vector quantized diffusion model for text-to-image synthesis

CVPR 2022论文分享会 - 基于VQ-Diffusion的文本到图像合成_哔哩哔哩_bilibiliCVPR 2022论文分享会 - 基于VQ-Diffusion的文本到图像合成, 视频播放量 1438、弹幕量 2、点赞数 38、投硬币枚数 12、收藏人数 40、转发人数 13, 视频作者 微软科技, 作者简介 大家好我是田老师&…

【电源专题】单节锂离子电池的保护的基本原理

为什么需要保护 锂离子电池在使用中最重要的是要确保它不会被过度充电和放电,这两种行为对它的伤害都是不可修复的,甚至可能还是危险的。因为它的内部材料结构被破坏了,就什么问题都可能表现出来。 因此使用中首先要做的就是要给它加上保护电路,确保过度充放电的行为不会…

系统报错msvcp120.dll丢失的解决方法,常见的三种解决方法

今天为大家讲述关于系统报错msvcp120.dll丢失的解决方法。在这个信息爆炸的时代&#xff0c;我们每个人都可能遇到各种各样的问题&#xff0c;而这些问题往往需要我们去探索、去解决。今天&#xff0c;我将带领大家走进这个神秘的世界&#xff0c;一起寻找解决msvcp120.dll丢失…