LeetCode刷题复盘笔记—一文搞懂0 - 1背包之474. 一和零问题(动态规划系列第十篇)

news2024/9/27 9:22:11

今日主要总结一下动态规划0-1背包的一道题目,474. 一和零问题

题目:416. 分割等和子集

Leetcode题目地址
题目描述:
给你一个二进制字符串数组 strs 和两个整数 m 和 n 。

请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。

如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。

示例 1:

输入:strs = [“10”, “0001”, “111001”, “1”, “0”], m = 5, n = 3
输出:4
解释:最多有 5 个 0 和 3 个 1 的最大子集是 {“10”,“0001”,“1”,“0”} ,因此答案是 4 。
其他满足题意但较小的子集包括 {“0001”,“1”} 和 {“10”,“1”,“0”} 。{“111001”} 不满足题意,因为它含 4 个 1 ,大于 n 的值 3 。
示例 2:

输入:strs = [“10”, “0”, “1”], m = 1, n = 1
输出:2
解释:最大的子集是 {“0”, “1”} ,所以答案是 2 。

提示:

1 <= strs.length <= 600
1 <= strs[i].length <= 100
strs[i] 仅由 ‘0’ 和 ‘1’ 组成
1 <= m, n <= 100

本题重难点

首先本道题容易存在一个误区:该题并不是多重背包,而是0 - 1背包的问题!

多重背包是每个物品,数量不同的情况。

本题中strs 数组里的元素就是物品,每个物品都是一个!
而m 和 n相当于是一个背包,两个维度的背包。
理解成多重背包的同学主要是把m和n混淆为物品了,感觉这是不同数量的物品,所以以为是多重背包。

但本题其实是01背包问题!
这不过这个背包有两个维度,一个是m 一个是n,而不同长度的字符串就是不同大小的待装物品。
大家在做这道题之前最好看一下一文搞懂纯0-1背包问题我对0-1背包的基础理论知识有详细的讲解,本道题其实就是0-1 背包问题的应用,而这道题的难点主要在于怎么把一和零问题问题抽象成一个0-1 背包问题。

上一篇一文搞懂纯0-1背包问题文章我们讲过背包问题,大家都知道,有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。
要注意题目描述中商品是不是可以重复放入。

即一个商品如果可以重复多次放入是完全背包,而只能放入一次是0-1背包,写法还是不一样的。

要明确本题中我们要使用的是0-1背包,因为元素我们只能用一次。

开始动规五部曲:

  1. 确定dp数组(dp table)以及下标的含义
    dp[i][j]:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]。

  2. 确定递推公式
    dp[i][j] 可以由前一个strs里的字符串推导出来,strs里的字符串有x个0,y个1。
    dp[i][j] 就可以是 dp[i - x][j - y] + 1。
    然后我们在遍历的过程中,取dp[i][j]的最大值。
    所以递推公式:dp[i][j] = max(dp[i][j], dp[i - x][j - y] + 1);
    此时大家可以回想一下01背包的递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
    对比一下就会发现,字符串的x和y相当于物品的重量(weight[i]),字符串本身的个数相当于物品的价值(value[i]),这个也是转化抽象成0 - 1背包问题的关键!!! 这就是一个典型的01背包! 只不过物品的重量有了两个维度而已。

  3. dp数组如何初始化
    在动态规划:关于01背包问题,你该了解这些!(滚动数组) (opens new window)中已经讲解了,01背包的dp数组初始化为0就可以。
    因为物品价值不会是负数,初始为0,保证递推的时候dp[i][j]不会被初始值覆盖。

  4. 确定遍历顺序
    在一文搞懂纯0-1背包问题中,我们讲了0 - 1背包为什么一定是外层for循环遍历物品,内层for循环遍历背包容量且从后向前遍历!
    那么本题也是,物品就是strs里的字符串,背包容量就是题目描述中的m和n。
    代码所示:

for (string str : strs) { // 遍历物品
    int x= 0, y= 0;
    for (char c : str) {
        if (c == '0') x++;
        else y++;
    }
    for (int i = m; i >= x; i--) { // 遍历背包容量且从后向前遍历!
        for (int j = n; j >= y; j--) {
            dp[i][j] = max(dp[i][j], dp[i - x][j - y] + 1);
        }
    }
}
  1. 举例推导dp数组

以输入:[“10”,“0001”,“111001”,“1”,“0”],m = 3,n = 3为例 最后dp数组的状态如下所示:
在这里插入图片描述

C++代码

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        vector<vector<int>>dp(m + 1, vector<int>(n + 1, 0));
        for(auto& str : strs){
            int x = 0, y = 0;
            for(auto& s : str){
                if(s == '0') x++;
                else y++;
            }
            for(int i = m; i >= x; i--){
                for(int j = n; j >= y; j--){
                    dp[i][j] = max(dp[i][j], dp[i - x][j - y] + 1);
                }
            }
        }
        return dp[m][n];
    }
};

总结

动态规划
英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。
动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的

对于动态规划问题,可以拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了!

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

这篇文章主要总结了一些动态规划解决一和零问题,依然是使用动规五部曲,做每道动态规划题目这五步都要弄清楚才能更清楚的理解题目!

不少同学刷过这道提,可能没有总结这究竟是什么背包。

此时我们讲解了0-1背包的多种应用,

1、纯 0 - 1 背包是求 给定背包容量 装满背包 的最大价值是多少。
2、416. 分割等和子集是求 给定背包容量,能不能装满这个背包。
3、1049. 最后一块石头的重量 II 是求 给定背包容量,尽可能装,最多能装多少
4、 494. 目标和 是求 给定背包容量,装满背包有多少种方法。 本题一和零问题是求 给定背包容量,装满背包最多有多少个物品。

欢迎大家关注本人公众号:编程复盘与思考随笔

(关注后可以免费获得本人在csdn发布的资源源码)

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

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

相关文章

【servelt原理_9_servlet应用___】

servlet应用*** 1.request对象 是当客户端向服务器端发送请求时&#xff0c;服务器为本次请求创建request对象&#xff0c;并在调用Servlet的service方法时&#xff0c;将该对象传递给service方法。Request对象中封装了客户端发送过来的所有的请求数据。 ①:doGet()方法接收r…

Maven详细总结

参考博客&#xff1a;https://blog.csdn.net/xiaodi2016/article/details/121341063 ※注意&#xff1a; 我们自己的Maven工程必须执行安装操作才会进入仓库。安装的命令是&#xff1a;mvn install 任何一个Maven工程会根据坐标到本地仓库中去查找它所依赖的jar包…

临近过年无情被裁,我面试大厂的这几个月…

秋招接近尾声&#xff0c;即将远去的“金九银十”今年也变成了“铜九铁十”。 大厂不断缩招&#xff0c;不容忽视的疫情影响&#xff0c;加上不断攀升的毕业生人数&#xff0c;各种需要应对的现实问题让整个求职季难上加难。 在这个异常残酷的求职季&#xff0c;很多人的困惑…

【intent-filter】AndroidManifest中<intent-filter>标签的 部分作用

这里写自定义目录标题AndroidManifest.xmlIntent-filter 标签Intent-filter 标签中的常用元素Intent-filter 标签的作用Intent对象Intent显式启动活动窗口Intent隐式启动&#xff08;重要&#xff09;AndroidManifest.xml AndroidManifest.xml是安卓开发中主配置文件&#xff…

【负荷预测】基于蚂蚁优化算法的BP神经网络在负荷预测中的应用研究(Matlab完整代码实现)

目录 0 知识回顾 1 ACO-BP算法 2 ACO-BP算法基本思路 3 具体步骤 4 Matlab代码实现 5 运行结果 6 参考文献 7 写在最后 0 知识回顾 智能优化算法—蚁群算法&#xff08;Python实现&#xff09; 1 ACO-BP算法 传统的BP神经网络训练采用的是误差反向传播学习算法,它的…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java高校教室申请管理系统yf80k

计算机毕业设计的编程真的不会, 应该怎么办啊, 平时学了3年都没学懂&#xff0c;然而还有一个月就要答辩了&#xff0c;一点东西都没做出来&#xff0c;不知道该怎么办了&#xff1f;好迷茫&#xff0c;如果毕不到业怎么办, 有没有快速的学习方法 毕设毕设&#xff0c;最终的是…

【C++面向对象程序设计】CH7 输入输出流

目录 一、前言 二、标准输出流 1.流对象 &#xff08;1&#xff09;cout流对象 &#xff08;2&#xff09;cerr流对象 &#xff08;3&#xff09;【例7.1】编写程序&#xff0c;从键盘输入a&#xff0c;b&#xff0c;c的值求解一元二次方程。如果a0或判别式的值<0&…

拾壹博客拆解改造,页面元素替换(二)

页面元素替换 首先要做的当然是换成自己风格的站名和内容啦。 1、网站配置 跟踪前端代码后发现配置是来自后端接口&#xff0c;想着既然入库了&#xff0c;那应该有对应的管理页面吧&#xff0c;果然找到了&#xff0c;就是…演示账号不允许操作&#xff01;那么接下来要干的…

stm32f767的fft

仅作自己笔记用 1&#xff0c;FFT函数调用基础知识 采样得到的数字信号&#xff0c;就可以做FFT变换了。N个采样点&#xff0c;经过FFT之后&#xff0c;就可以得到N个点的FFT结果。为了方便进行FFT运算&#xff0c;通常N取2的整数次方。 假设采样频率为Fs&#xff0c;信号频率…

基于Java环境下的高校跳蚤市场商城系统

目 录 摘 要 I Abstract II 1绪论 1 1.1 课题背景 1 1.2 目的和意义 1 1.3 研究现状 2 1.4 研究主要内容 3 2开发平台与技术的介绍 4 2.1 Eclipse简介 4 2.2 Java EE简介 4 2.2.1 Java EE概念 4 2.2.2 Java EE运行模式 4 2.3 Jsp技术简介 5 2.4 Struts 2框架简介 5 2.5 MySQL简…

[附源码]计算机毕业设计springboot新冠疫苗接种预约系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Docker最新超详细教程——Docker创建运行Redis并挂载

Docker最新超详细教程——Docker创建运行Redis并挂载 Docker官网关于Redis的描述 redis - Official Image | Docker Hubhttps://hub.docker.com/_/redis 一、拉取Redis镜像 docker pull <镜像名称>:<版本号> docker pull redis:6.2.27 首先我们要在Docker上获取…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java高校教学过程管理系统34085

现在毕设刚开始。时间还有很多&#xff0c;可以从头开始学也可以。毕设其实不难&#xff0c;难的是我们懒散到这种时候再去静下心学。能自己独立完成尽量自己独立完成。相信你看过很多上面回答的&#xff0c;都不建议去某宝。毕竟这一行参差不齐哈。能找到靠谱的也不容易。近期…

Unity Debug的简单封装

对Unity Debug的简单封装 使用前提&#xff1a; Project Settings-Player-Other Settings-Script Define Symbols添加 EnableLog&#xff0c;点击Apply 测试代码&#xff1a; using MTools.Debuger; using UnityEngine;public class NewBehaviourScript : MonoBehaviour {p…

基于PHP+MySQL家庭医生签约预约诊疗管理信息系统

随着时代的发展,人们对医疗方面的要求也越来越高,也是人们更希望通过家庭医生来对自己提供所需的医疗服务,从而享受更加个性化的医疗服务,为此我们开发了本家庭医生签约预约诊疗管理信息系统,通过本系统患者可以享有签约,预约,和诊疗等一系类的服务。 本系统是一个家庭医生签约…

[附源码]Python计算机毕业设计Django基于微信小程序的网络办公系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

qmake 参数

E:\workspace\QtWork\qmake\option.cpp:Option::init() -project 设置qmake生成工程相关文件&#xff0c;如果用qt creator开发的话这个命令参数基本用不到。 -prl 设置qmake生成prl文件。 -set 设置自定义属性&#xff0c;会存放到注册表中。具体参考属性 -unset 取消自定义…

网页JS自动化脚本(六)在特定位置添加元素

在某元素后插入元素 我们这一次在按钮元素后面复制一个一模一样的按钮,所以分为几个步骤,先新建一个一样的元素,然后把相同中的属性赋值给它,再插入到合适的位置,最后再稍微修改一下外观样式即可 首先新建一个input元素,看一下效果 window.onloadfunction(){var theElementdo…

[附源码]Python计算机毕业设计Django基于人脸识别的社区防疫管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Pytest自动化测试框架---(单元测试框架)

unittest是python自带的单元测试框架&#xff0c;它封装好了一些校验返回的结果方法和一些用例执行前的初始化操作&#xff0c;使得单元测试易于开展&#xff0c;因为它的易用性&#xff0c;很多同学也拿它来做功能测试和接口测试&#xff0c;只需简单开发一些功能&#xff08;…