代碼隨想錄算法訓練營|第四十九天|139.单词拆分、关于多重背包、背包问题总结。刷题心得(c++)

news2024/9/23 11:18:00

目录

讀題

139.单词拆分

自己看到题目的第一想法

看完代码随想录之后的想法

139.单词拆分 - 實作

思路

Code

關於多重背包

與01背包與完全背包的差別

轉化成01背包問題

背包问题总结

背包問題分類

背包問題 - 遞推公式

最多裝多少/能否裝滿

最大價值

裝滿背包有多少方式

最少裝多少/能否裝滿

遍歷順序差異

01背包

完全背包

總結

總結

自己实现过程中遇到哪些困难

今日收获,记录一下自己的学习时长

相關資料


讀題

139.单词拆分

自己看到题目的第一想法

看到的當下有點矇,不知道該怎麼去解,我要如何去做?

誰是背包誰是物品也沒有搞清楚,直接看題解。

看完代码随想录之后的想法

單詞就是物品,字符串s就是背包,單詞能否組成字符串,可以想成物品能不能把背包裝滿

拆分的過程中,可以重複單詞,就表示這不是01背包問題,而是完全背包問題

因為遍歷物品的時候,子字符串都是從j = 0 開始,所以不用擔心dp[i] 之間的如果都是false

因為dp[0] = 1 這是構成這套方式可以成功執行的關鍵之一

139.单词拆分 - 實作

思路

  1. 定義DP數組以及下標的含意

    dp[i]: 字符串長度i,如果dp[i] 為true,代表有一個或多個字典元素所組成。

  2. 遞推公式

    如果dp[j] (可以想成子字符串的起點) 為true,代表之前的數值是由一個或多個字典元素所組成。

    所以如果[j - i] 也就是j 到 i 的區間子串有出現在字典元素當中,代表dp[i] 也為true

    遞推公式為: if([j, i] == word_Dict && dp[j] == true) dp[i] = true;

  3. 根據遞推公式,確定DP數組如何初始化

    dp[0] = true, 可以想成沒有任何字串的狀況下,有一種方法可以組成字符串長度為0,會比較好理解。

  4. 確定遍歷順序

    在字符串長度遍歷的過程中,比如說’aba’ 字典裡有a, b

    雖然aab 也是字符串有的元素,只是排列不同但aab ≠ aba

    所以我們求的是排列,需要先遍歷背包在遍歷物品

Code

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> wordSet(wordDict.begin(), wordDict.end()); //建立wordDict 讓後續程式可以快速查找
        vector<bool> dp(s.size() + 1, false);
        dp[0] = true;

        for(int i = 0; i <= s.size(); i++) {
            for(int j = 0; j < i; j++) {
                string word = s.substr(j, i - j); //[j,i] 的子串
                if(wordSet.find(word) != wordSet.end() && dp[j]) {
                    dp[i] = true;
                }
            }
        }
        return dp[s.size()];
    }
};

 

關於多重背包

與01背包與完全背包的差別

01 背包: 物品有兩個維度的資料: 價值、重量,數量則只能有一個

完全背包: 物品有兩個維度的資料: 價值、重量,數量則有無限個,可以重複取相同物品

多重背包: 物品變為有三個維度的資料: 價值、重量、數量,並且可以重複取

跟01背包有點像,將數量展開,其實就是01背包,一樣是取與不取,只是數據上有許多相同物品

跟完全背包也有點像,因為可以重複取相同的物品,只是數量有限

轉化成01背包問題

其實在剛剛提到多重背包可以轉化成01背包

在代碼隨想錄中有相關的code,主要轉化的過程如下

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]--;
        }
    }

透過展開物品,讓問題轉化成01背包問題

或者透過多加一層嵌套的迴圈,也就是遍歷物品時,將數量全部都跑過一次

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

 

背包问题总结

背包問題分類

背包問題 - 遞推公式

最多裝多少/能否裝滿

dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]); → 可以想像成物品重量與價值相等

對應題目

  • 动态规划:416.分割等和子集(opens new window)
  • 动态规划:1049.最后一块石头的重量 II

最大價值

dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); → 可以想像成物品重量與價值不相等

對應題目

  • 动态规划:474.一和零

裝滿背包有多少方式

dp[j] += dp[j - nums[i]];

對應題目

  • 动态规划:494.目标和(opens new window)
  • 动态规划:518. 零钱兑换 II(opens new window)
  • 动态规划:377.组合总和Ⅳ(opens new window)
  • 动态规划:70. 爬楼梯进阶版(完全背包)

最少裝多少/能否裝滿

dp[j] = min(dp[j - coins[i]] + 1, dp[j])

對應題目

  • 动态规划:322.零钱兑换(opens new window)
  • 动态规划:279.完全平方数

遍歷順序差異

01背包

  • 二維dp

    因為數值都會根據左上方以及正上方的值進行更新,所以當我們初始化第一行與第一列時,不管是從背包開始遞推還是物品開始遞推,都可以。

    第二層遍歷順序是由小到大

  • 一維dp

    在二维數組中,每一層的數值都是當前位置的正上方以及左上方的數據得出

    從二维壓縮成一维數組,我們需要模擬二维數組的方式

    所以根據我們的遞推公式,我們不能使用正序遍歷,不然原本在二维數組中左上方的數據就會被覆蓋掉

    而使用倒序可以保證每一層的數據都是由二维數組上一層正上方以及左上方得出的。

  • 二維dp 滾動dp

    在**动态规划:474.一和零 中是有兩個維度的背包**

    先遍歷物品,在遍歷二維背包

    因為是滾動數組,所以二維背包是由後往前遍歷

完全背包

在純完全背包的問題當中,既然物品可以被選取無限次,那麼考慮某個物品時不必限制只看一次。

換句話說,可以在考慮這個物品的同時也考慮其他所有的物品。

因此,不論先遍歷物品還是先遍歷容量,結果都是一樣的。

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

  • 求最小数:动态规划:322. 零钱兑换 (opens new window)动态规划:279.完全平方数

但如果題目要求的回答是組合或者是排序就會有所差別

組合 - 不要求順序性: 外層遍歷物品內層遍歷背包

排列- 要求順序性: 外層遍歷背包內層遍歷物品

相關題目

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

可以想像在求組合的時候,外層遍歷物品,確保每個背包至多只會有一次的組合

但在求排序時,因為每個背包都會重新遍歷物品,所以會有不同的順序被計算到

總結

在學習背包問題時,其實最有感的就是如何看待問題使其可以用背包問題的角度切入

並且如何透過這個切角去推出遞推公式以及遍歷的順序

每個題目其實去細細思考,都會有很多不一樣的體會。

總結

自己实现过程中遇到哪些困难

真的需要去把set跟map釐清,自己在看到單詞拆分講解時才豁然開朗,並且這次的題目比較抽象,自己之前沒有太多相關的經驗,所以學習起來需要花更多時間去處理

今日收获,记录一下自己的学习时长

今天大概學了1.5 hr,主要是在統整自己對於背包問題的歸納以及了解多重背包。

相關資料

● 今日学习的文章链接和视频链接

139.单词拆分

视频讲解:动态规划之完全背包,你的背包如何装满?| LeetCode:139.单词拆分_哔哩哔哩_bilibili

https://programmercarl.com/0139.单词拆分.html

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

https://programmercarl.com/背包问题理论基础多重背包.html

背包问题总结篇!

https://programmercarl.com/背包总结篇.html

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

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

相关文章

OpenFeign实现分析、源码解析

什么是openfeign? 是springcloud全家桶的组件之一&#xff0c;其核心作用是为Rest API提供高效简洁的rpc调用方式。 为什么只定义接口而没有实现类&#xff1f; 源码解读&#xff08;省略&#xff09; 总结&#xff1a; 源码分析&#xff1a;如何发送http请求&#xff1f; …

基于单片机设计的智能窗帘控制系统

一、前言 智能家居技术在近年来取得了巨大的发展&#xff0c;并逐渐成为人们日常生活中的一部分。智能家居系统带来了便利、舒适和高效的生活体验&#xff0c;拥有广泛的应用领域&#xff0c;其中之一就是智能窗帘控制系统。 传统窗帘需要手动操作&#xff0c;打开或关闭窗帘…

微服务-Ribbon负载均衡

文章目录 负载均衡原理流程原理源码分析负载均衡流程 负载均衡策略饥饿加载总结 负载均衡原理 流程 原理 LoadBalanced 标记RestTemplate发起的http请求要被Ribbon进行拦截和处理 源码分析 ctrlshiftN搜索LoadBalancerInterceptor&#xff0c;进入。发现实现了ClientHttpRequ…

Snipaste--强大的截图贴图软件--非常实用

一.软件介绍&#xff1a; Snipaste 是一个简单但强大的截图工具&#xff0c;也可以让你将截图贴回到屏幕上&#xff01;下载并打开Snipaste&#xff0c;按下 F1 来开始截图&#xff0c;再按 F3&#xff0c;截图就在桌面置顶显示了。就这么简单&#xff01;你还可以将剪贴板里的…

SK-Net eca注意力机制应用于ResNet (附代码)

resnet发展历程 论文地址&#xff1a;https://arxiv.org/pdf/1903.06586.pdf 代码地址&#xff1a;https://github.com/pppLang/SKNet 1.是什么&#xff1f; SK-net网络是一种增加模块嵌入到一些网络中的注意力机制&#xff0c;它可以嵌入和Resnet中进行补强&#xff0c;嵌入…

composer安装thinkphp6报错

composer安装thinkphp6报错&#xff0c; 查看是否安装了对应的PHP扩展&#xff0c;我这边使用的是宝塔的环境&#xff0c;全程可以可视化操作 这样就可以安装完成了

linux工具篇

文章目录 linux工具篇1. linux 软件包管理器-yum1.1 什么是软件包1.2 yum的使用1.3 yum源 2. linux编辑器-vim2.1 vim概念2.2 vim各个模式切换2.3 vim正常模式命令汇总2.4 vim底行模式各命令汇总2.5 vim的简单配置 3. Linux编译器-gcc/g使用3.1 复习程序编译过程(1) 预处理(2) …

【Oracle】Navicat Premium 连接 Oracle的两种方式

Navicat Premium 使用版本说明 Navicat Premium 版本 11.2.16 (64-bit) 一、配置OCI 1.1 配置OCI环境变量 1.1.2 设置\高级系统设置 1.1.2 系统属性\高级\环境变量(N) 1.1.3 修改/添加系统变量 ORACLE_HOME ORACLE_HOME D:\app\root\product\12.1.0\dbhome_11.1.4 添加系…

Redis快速上手篇(一)(安装与配置)

NoSQL NoSQL 是 Not Only SQL 的缩写&#xff0c;意即"不仅仅是 SQL"的意思&#xff0c;泛指非关系型的数据库。强调 Key-Value Stores 和文档数据库的优点。 NoSQL 产品是传统关系型数据库的功能阉割版本&#xff0c;通过减少用不到或很少用的功能&#xff0c;来大…

vue3中使用svg并封装成组件

打包svg地图 安装插件 yarn add vite-plugin-svg-icons -D # or npm i vite-plugin-svg-icons -D # or pnpm install vite-plugin-svg-icons -D使用插件 vite.config.ts import { VantResolver } from unplugin-vue-components/resolvers import { createSvgIconsPlugin } from…

【C语言初阶】switch语句的基本语法

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《速学C语言》《数据结构篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言&#x1f4ac; switch语句的介绍&#x1f4ac; switch语句的语法形式&#x1f4ad; 在switch语句中的 break&…

景联文科技提供4D-BEV标注工具:提升自动驾驶感知能力的精准数据支持

4D-BEV标注是一种用于自动驾驶领域的数据标注方法。在3D空间的基础上&#xff0c;加入了时间维度&#xff0c;形成了四个维度。这种方法通过精准地跟踪和记录动态对象&#xff08;如车辆、行人&#xff09;的运动轨迹、姿势变化以及速度等信息&#xff0c;全面理解和分析动态对…

JWT的登录认证与自校验原理分析

目录 一、JWT的概述 1.什么是JWT&#xff1f; 2.JWT的用户认证 3.JWT解决了什么问题&#xff1f; 4.关于JWT中的签名如何理解&#xff1f; 5.JWT的优势 二、JWT的结构 1.令牌的组成&#xff1a; 2.JWT的工具类 3.JWT所需的依赖 4.JWT登录生成Token的原理 三、JWT的自…

Linux中关于glibc包导致的服务器死机或者linux命令无法使用的情况

glibc是gnu发布的libc库&#xff0c;即c运行库。glibc是linux系统中最底层的api&#xff0c;几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外&#xff0c;它本身也提供了许多其它一些必要功能服务的实现。由于 glibc 囊括了几乎所有的 UNIX …

智能巡检系统可以应用在哪些地方?巡检系统有什么优势?

智能巡检系统可以广泛应用于学校、物业、工厂、酒店和民宿、运维商以及能源行业等不同领域的巡检管理之中&#xff0c;为用户提供了巡检任务安排管理、签到打卡、工单上报处理以及数据统计分析等多种功能。 一、巡检系统的应用场景   1、学校&#xff1a;为了确保学校各项设施…

【抓包分析】通过ChatGPT解密还原某软件登录算法实现绕过手机验证码登录

文章目录 &#x1f34b;前言实现效果广告抓包分析一、定位加密文件二、编辑JS启用本地替换 利用Chatgpt进行代码转换最后 &#x1f34b;前言 由于C站版权太多&#xff0c;所有的爬虫相关均为记录&#xff0c;不做深入&#xff01; 今天发现github上没有这个东西&#xff0c;抓…

Centos7 防火墙的关闭

Centos7 防火墙的关闭 Centos7默认使用的是firewall作为防火墙&#xff1b; 查看防火墙状态&#xff1a;firewall-cmd --state 停止防火墙&#xff1a;systemctl stop firewalld.service; 禁止防火墙开机启动&#xff1a;systemctl disable firewalld.service; 放行端口…

项目总结-新增商品-Pagehelper插件分页查询

&#xff08;1&#xff09;新增商品 工具类&#xff1a; /** * Title: FileUtils.java * Package com.qfedu.common.utils * Description: TODO(用一句话描述该文件做什么) * author Feri * date 2018年5月29日 * version V1.0 */ package com.gdsdxy.common.u…

webpack 解决:TypeError: merge is not a function 的问题

1、问题描述&#xff1a; 其一、存在的问题为&#xff1a; TypeError: merge is not a function 中文为&#xff1a; 类型错误&#xff1a;merge 不是函数 其二、问题描述为&#xff1a; 想执行 npm run dev 命令&#xff0c;运行起项目时&#xff0c;控制台报错 TypeErro…

066:mapboxGL的marker的drag,dragstart,dragend三种触发事件示例

第066个 点击查看专栏目录 本示例是演示如何在vue+mapbox中处理marker的三种触发事件drag,dragstart,dragend。 marker通过on(‘XXX’, callback),的方式进行触发处理。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(…