代码随想录算法训练营 Day 46 | 139.单词拆分,关于多重背包,你该了解这些!,背包问题总结篇!

news2024/12/24 10:28:47

139.单词拆分

讲解链接:代码随想录-139.单词拆分

  1. 确定 dp 数组以及下标的含义:dp[i] : 字符串长度为 i 的话,dp[i]为 true,表示可以拆分为一个或多个在字典中出现的单词。

  2. 确定递推公式:如果确定 dp[j] 是 true,且 [j, i] 这个区间的子串出现在字典里,那么 dp[i]一定是 true。(j < i )。
    所以递推公式是 if([j, i] 这个区间的子串出现在字典里 && dp[j]是 true) 那么 dp[i] = true。

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

  4. 确定遍历顺序:题目中说是拆分为一个或多个在字典中出现的单词,所以这是完全背包。还要讨论两层 for 循环的前后顺序。

    1. 如果求组合数就是外层 for 循环遍历物品,内层 for 遍历背包。
    2. 如果求排列数就是外层 for 遍历背包,内层 for 循环遍历物品。
    3. 而本题其实我们求的是排列数,为什么呢。 拿 s = "applepenapple", wordDict = ["apple", "pen"] 举例。
      "apple", "pen" 是物品,那么我们要求 物品的组合一定是 "apple" + "pen" + "apple" 才能组成 "applepenapple"。
      "apple" + "apple" + "pen" 或者 "pen" + "apple" + "apple" 是不可以的,那么我们就是强调物品之间顺序。
      所以说,本题一定是 先遍历 背包,再遍历物品。
public boolean wordBreak(String s, List<String> wordDict) {
    boolean[] dp = new boolean[s.length() + 1];
    dp[0] = true;

    for (int i = 1; i < dp.length; i++) {
        for (int j = 0; j < wordDict.size(); j++) {
            String str = wordDict.get(j);
            Integer len = str.length();
            if (i >= len && dp[i - len] && str.equals(s.substring(i - len, i))) {
                dp[i] = true;
                break;
            }
        }
    }

    return dp[dp.length - 1];
}

关于多重背包,你该了解这些!

讲解链接:代码随想录-关于多重背包,你该了解这些! 

版本二:改变遍历个数

public void testMultiPack2() {
    // 版本二:改变遍历个数
    int[] weight = new int[]{1, 3, 4};
    int[] value = new int[]{15, 20, 30};
    int[] nums = new int[]{2, 3, 2};
    int bagWeight = 10;

    int[] dp = new int[bagWeight + 1];
    for (int i = 0; i < weight.length; 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] = Math.max(dp[j], dp[j - k * weight[i]] + k * value[i]);
            }
            System.out.println(Arrays.toString(dp));
        }
    }
}

版本一:改变物品数量为 01 背包格式

public void testMultiPack1() {
    // 版本一:改变物品数量为01背包格式
    List<Integer> weight = new ArrayList<>(Arrays.asList(1, 3, 4));
    List<Integer> value = new ArrayList<>(Arrays.asList(15, 20, 30));
    List<Integer> nums = new ArrayList<>(Arrays.asList(2, 3, 2));
    int bagWeight = 10;

    for (int i = 0; i < nums.size(); i++) {
        while (nums.get(i) > 1) { // 把物品展开为i
            weight.add(weight.get(i));
            value.add(value.get(i));
            nums.set(i, nums.get(i) - 1);
        }
    }

    int[] dp = new int[bagWeight + 1];
    for (int i = 0; i < weight.size(); i++) { // 遍历物品
        for (int j = bagWeight; j >= weight.get(i); j--) { // 遍历背包容量
            dp[j] = Math.max(dp[j], dp[j - weight.get(i)] + value.get(i));
        }
        System.out.println(Arrays.toString(dp));
    }
}

背包问题总结篇!

讲解链接:代码随想录-背包问题总结篇!

01 背包

在动态规划:关于 01 背包问题,你该了解这些! 中我们讲解二维 dp 数组 01 背包先遍历物品还是先遍历背包都是可以的,且第二层 for 循环是从小到大遍历。

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

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

完全背包

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

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

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

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

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

相关题目如下:

  • 求组合数:动态规划:518.零钱兑换 II
  • 求排列数:动态规划:70. 爬楼梯进阶版(完全背包)

如果求最小数,那么两层 for 循环的先后顺序就无所谓了,相关题目如下:

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

对于背包问题,其实递推公式算是容易的,难是难在遍历顺序上,如果把遍历顺序搞透,才算是真正理解了。

总结

​​

 

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

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

相关文章

PyTorch-Dataset

Dataset类&#xff1a; 如何获取数据及标签。 Dataloader类&#xff1a;为之后的网络提供不同的数据形式。 1. 数据文件夹表示&#xff1a; from torch.utils.data import Dataset from PIL import Image import osclass MyData(Dataset):def __init__(self, root_dir, label_d…

三十七、雪崩问题、Sentinel、簇点链路、流控模式

1、初识Sentinel 1.1雪崩问题 微服务调用链路中的某个服务故障&#xff0c;引起整个链路中的所有微服务都不可用&#xff0c;这就是雪崩。 解决雪崩问题的常见方式有四种&#xff1a; 超时处理&#xff1a;设定超时时间&#xff0c;请求超过一定时间没有响应就返回错误信息&am…

Rust每日一练(Leetday0006) 三数之和、字母组合、四数之和

目录 16. 最接近的三数之和 3Sum Closest &#x1f31f;&#x1f31f; 17. 电话号码的字母组合 Letter-combinations-of-a-phone-number &#x1f31f;&#x1f31f; 18. 四数之和 4Sum &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust…

肝一肝设计模式【九】-- 享元模式

系列文章目录 肝一肝设计模式【一】-- 单例模式 传送门 肝一肝设计模式【二】-- 工厂模式 传送门 肝一肝设计模式【三】-- 原型模式 传送门 肝一肝设计模式【四】-- 建造者模式 传送门 肝一肝设计模式【五】-- 适配器模式 传送门 肝一肝设计模式【六】-- 装饰器模式 传送门 肝…

java枚举类解读

目录 为什么需要枚举类 枚举类的使用 枚举类的实现 枚举类的属性 自定义枚举类 使用enum定义枚举类 常见enum的使用场景 switch 向枚举中添加新方法 覆盖枚举的方法 Enum类的主要方法 实现接口的枚举类 为什么需要枚举类 类的对象只有有限个&#xff0c;确定的。…

如何将map与对象进行转换

Spring Boot内置了一个强大的JSON转换器Jackson&#xff0c;可以实现将JSON字符串或Map类型的数据转换成Java对象。以下是将Map类型的数据转换成Java对象的示例代码&#xff1a; import com.fasterxml.jackson.databind.ObjectMapper;//定义Java对象 public class User {priva…

oracle客户端的安装教程

文章目录 一、安装前的准备工作 1.1、百度网盘安装包的连接 1.2、百度网盘oracle11g软件包 二、oracle数据库客户端的安装与数据的准备 安装步骤 前言 本文主要讲解oracle客户端的安装与简单使用过程 一、安装前的准备工作 1.1、百度网盘安装包的连接 客户端的软件包 …

STM32 FMC篇-SDRAM(IS42S16400J)

IS42S16400J 这个东西太常见啦&#xff0c;长方形的。不会过多解释&#xff0c;详细请阅读它的数据手册。 IS42S16400J是一种高速同步动态随机存储器(SDRAM)&#xff0c;64Mb的存储容量&#xff0c;采用4个bank&#xff0c;每个bank大小为16Mb&#xff0c;总线宽度为16位&…

【CW32开发】00 开发环境搭建和示例代码运行

1.下载MDK 2.下载芯片相关的固件库 我用的是芯片是CW32F030系列&#xff0c;所以下载相应的固件库 下载地址&#xff1a;https://www.whxy.com/support/filelist/13 3.安装固件库 解压下载的文件&#xff0c;并在cw32f030-stdperiph-lib\IdeSupport\MDK路径下安装固件库 …

064:cesium设置点划线材质(material-8)

第064个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中设置点划线材质,请参考源代码,了解PolylineDashMaterialProperty的应用。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共89行)相关API参考:专栏…

CBFS Vault 2022 for .NET Crack

将多个文件打包到一个 Vault - 一个“文件中的文件系统”&#xff0c;完成每个文件的压缩、透明加密和随机读/写访问。 亮点包括新的日记选项、用于更好地控制和跟踪的新事件&#xff0c;以及一系列核心性能和可用性改进 [了解更多]。 CBFS保险库 在任何地方存储一个完整的文件…

chatgpt赋能Python-pythone怎么下载

Python下载&#xff1a;在SEO中的作用 介绍 Python是一种广泛应用于编程、自动化任务和数据处理的强大语言。在SEO中&#xff0c;Python也扮演了越来越重要的角色。Python有许多库和工具可供下载&#xff0c;这使得它成为了SEO领域中必不可少的一部分。在本文中&#xff0c;我…

人工智能之读懂CNN卷积神经网络

通过往期文章的分享,我们了解了神经网络的结构,一般分为输入层,隐藏层,输出层 TensorFlow神经网络 那什么是卷积神经网络那,这就要我们追溯一下人类识别图像的原理 人类的视觉原理如下:从原始信号摄入开始(瞳孔摄入像素 Pixels),接着做初步处理(大脑皮层某些细胞发现…

chatgpt赋能Python-pythondna匹配

Python DNA匹配&#xff1a;从概念到应用 概述 DNA匹配是生物学中的一个重要领域&#xff0c;它意味着找到两个DNA序列之间的相似性并确定它们之间的关系。Python是一种被广泛用于生物信息学中的编程语言&#xff0c;它提供了一系列强大的库和工具来处理DNA序列数据&#xff…

【C++从0到王者】第七站:内存管理(520没有对象?那就new一个)

文章目录 一、C/C内存分区二、C语言中动态内存管理方式三、C内存管理方式1.new/delete操作内置类型2.C为什么要搞new和delete3.C中new和delete操作自定义类型4.非要乱用delete和free会造成什么后果&#xff1f; 四、 operator new与operator delete函数五、operator new和opera…

在安卓中压缩GIF的几种方法(附实例代码)

前言 最近在划水摸鱼的时候&#xff0c;看到有位大佬发了一篇 GIF 压缩思路的文章。 让我突然想起来&#xff0c;很久以前我在我的项目 隐云图解制作 中就实现了一个动图工具箱&#xff0c;其中一个功能就是压缩GIF。 不过这位大佬只介绍了其中几种使用方法&#xff0c;还有…

Java动态类型语言支持

JDK7发布字节码首位新成员——invokedynamic指令。以实现动态类型语言支持。也是为JDK8里可以顺利实现Lambda表达式而做的技术储备。我们将在本文详细了解动态语言支持这项特性出现的背景和它的意义与价值。 1 动态类型语言 动态类型语言的关键特征是它的类型检查的主体过程是…

MJ discord 添加应用配置

discord 添加机器人 https://discord.com/developers/applications 刷新token后显示&#xff0c;即机器人Token&#xff0c;后续配置到 mj.discord.bot-token 如图勾选后&#xff0c;打开url进行授权 选择Midjourney Bot所在的服务器 勾上这两个选项&#xff0c;点击 Save Cha…

图片转Excel表格,识别准确率的重要性

摘要&#xff1a;随着科技的不断发展&#xff0c;图片转Excel表格的应用越来越广泛。通过OCR技术实现图片转Excel表格&#xff0c;OCR识别准确率的提高对于信息录入的精度以及后续数据分析的可靠性具有非常重要的作用。本文探讨了影响OCR识别准确率的因素&#xff0c;并提出了提…

2.MATLAB篇——基本操作与矩阵输入

>> cos(((12345)^5)^0.5)ans -0.3623>> help sinsin - 参数的正弦&#xff0c;以弧度为单位此 MATLAB 函数 返回 X 的元素的正弦。sin 函数按元素处理数组。该函数同时接受实数和复数输入。 对于 X 的实数值&#xff0c;sin(X) 返回区间 [-1, 1] 内的实数值。 对于…