当前位置: 首页 > news >正文

01背包问题(大彻大悟版)

背包问题身为一个非常经典的动态规划问题,理清思路很重要,在经过多次观看y总视频和b站解析,加上CSDN的文章辅助,我终于从很多不理解到大彻大悟,下面是我对于背包问题思路的总结,有问题的话欢迎指出。

谈到背包问题,先以下面这最经典的一道背包问题为例子


有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。

第 i 件物品的体积是 vi,价值是 wi。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 ii 件物品的体积和价值。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N,V≤1000

0<vi,wi≤1000

输入样例

4 5
1 2
2 4
3 4
4 5

输出样例:

8

不废话,直接给出两种思路(可以结合看)

  1. bilibili表格法

b站中把背包问题转化为一个表格来理解,我觉得特别有用,对于背包问题光是靠说是很难理解的,通过表格总结公式和方法,对于该题非常有效,入门背包问题必须要看看。(链接:【【动态规划】背包问题】 https://www.bilibili.com/video/BV1K4411X766/?share_source=copy_web&vd_source=7e63f1b6fa68c511b241d12721f0a4bc

先从一个具体例子入手

对于所给定的背包容量和物品状态,我们需要找出价值最大的一个组合,通过画图

假设这是一个f(i,j)的数组,则每一个f(i,j)的值都是前i(物品编号)件物品中,不超过j(背包容量)体积下的最大值

注意:重中之重每个格子是只考虑前i件物品 当时我比较不能理解的是为什么只考虑前i件物品下不超过该体积的值,编号i之后的物品不也可以放入该体积容量,假如该方法价值更高,那不是就不是该背包体积下最大价值了。

当时就是不能理解啊,后面思考之后终于悟了,表格是所有情况都能考虑到,因为每个格子是在选了和不选的情况下取的最大值,我们只要只考虑前i件物品,后面每一个格子就能由前面的推出来,也能得到一个公式。

比如这题假如我们要算第f(4,8)的值,也就是该条件的最大价值,假设我们不知道该值,前面的数据我们都是知道的,因此第4件物品有选和不选两种情况,如果不选,f(4,8)=f(3,8),本来需要考虑前4个,现在只需要考虑前3个,而f(3,8)前面是已经算出来了。假如选,则需要满足一个条件,即此时背包剩余的容量一定大于第四件物品体积,在此前提下,我们选了第4件物品,然后往前找,选了4之后我们表格应该找到f(3,8-第四件物品体积)也就是f(3,3),此时只考虑前3个物品,即f(4,8)=第四件物品价值+f(3,3),因为前面的f都是已经计算出来对应条件的价值最大值了,f(4,8)的值也就出来了。最后,在选和不选中取一个最大值即使f(4,8)的值。

用表格容易理解,但确定是该方法不容易运用到其他同题型中,下面给出第二种

2.闫式DP分析法

此方法比较有规律和逻辑,但对于新手不容易理解(nnd当时我看了好多遍才懂),但是第一种懂了,第二种也应该学习,因为该方法会了之后同题型就变得很简单了,后面我也会发类似题目的博客,用该方法来做,会发现简单很多。

大致思路与第一种是差不多的,也是把f(i,j)分为两种情况,这里不多做解释,和第一种同理

该方法很系统的对于该类题型的做题方法做了一个总结,此时f(i,j)为一个集合,每个f(i,j)的内容需要其属性来判断,背包问题要求我们找最大值,即属性为max,因此f(i,j)为对应条件下的最大值,然后进行状态计算,如何计算f(i,j),找到最后一个不同点进行划分,对于其他题型我们只需要对f(i,j)进行不同情况的划分考虑完就可以了。

状态计算的核心:如何将现有的集合划分为更小的子集,使得所有子集都可以计算出来,这是我们需要做的事

说了这么多,没有代码就是空谈

代码如下:(第一种和第二种方法都一样代码)

#include<iostream>
using namespace std;
const int N=1010;
int f[N][N];
int v[N],w[N];
int main()
{int n,m;cin>>n>>m;for(int i=1;i<=n;i++) cin>>v[i]>>w[i];for(int i=1;i<=n;i++)//i代表物品,第一件开始考虑for(int j=0;j<=m;j++)//j代表背包容量,可以为0(一件都不选),因此从0开始{f[i][j]=f[i-1][j];//不选第i个物品if(j>=v[i]) f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);//选第i个物品}cout<<f[n][m]<<endl;return 0;
}

对于该代码我们是可以进行优化的,把二维转化为一维可以节省空间和时间,这里也给出优化后的代码,想要了解为什么的这里也给出一个链接https://www.acwing.com/solution/content/1374/,里面解释的非常好,这里我就不多阐明

优化后的代码:

#include<iostream>
using namespace std;
const int N=1010;
int f[N];
int v[N],w[N];
int main()
{int n,m;cin>>n>>m;for(int i=1;i<=n;i++) cin>>v[i]>>w[i];for(int i=1;i<=n;i++)for(int j=m;j>=v[i];j--)//这里为什么从后往前遍历,因为为了防止第i层前面先被更新{f[j]=max(f[j],f[j-v[i]]+w[i]);}cout<<f[m]<<endl;return 0;
}

最后祝大家早日理解背包问题,把动态规划用的行云流水,以后也会常更新dp的!!!

相关文章:

01背包问题(大彻大悟版)

背包问题身为一个非常经典的动态规划问题&#xff0c;理清思路很重要&#xff0c;在经过多次观看y总视频和b站解析&#xff0c;加上CSDN的文章辅助&#xff0c;我终于从很多不理解到大彻大悟&#xff0c;下面是我对于背包问题思路的总结&#xff0c;有问题的话欢迎指出。谈到背…...

【麒麟服务器操作系统忘记开机密码怎么办?---银河麒麟服务器操作系统更改用户密码】

银河麒麟服务器操作系统更改用户密码 1.启动主机进入 grub 菜单&#xff0c;如图 1.1 以最新版本 Kylin-Server-10-SP2-x86-Release-Build09-20210524 为例。 图 1.1 grub 菜单 2 编辑 kernel 2.1按下”e”输入&#xff0c;输入用户名和密码&#xff08;root/Kylin123123&…...

华为OD机试(20222023)考点分类

字符串,数组,集合操作 题库分值序号题目考点 or 实现Old1001敏感字段加密字符串,数组,集合操作Old1002IPv4地址转换成整数字符串,数组,集合操作Old1006字符串分割字符串,数组,集合操作Old1007...

初级篇 3 - HTML 或 CSS 文件中不懂的标签属性详解

目录一、遇到的不懂的标签属性详解1、meta 标签的 http-equiv 属性(元标签)二、遇到的 CSS 不懂的属性详解vertical-align三、如何规避 HTML 自动换行 - 脱离文档流配置属性 display: inline-block理解 inline、inline-block、blockinline总结&#xff1a;四、导航栏自动弹出子…...

【C语言】每日刷题 —— 牛客语法篇(4)

&#x1f680;&#x1f680;前言 大家好&#xff0c;继续更新专栏 c_牛客&#xff0c;不出意外的话每天更新十道题&#xff0c;难度也是从易到难&#xff0c;自己复习的同时也希望能帮助到大家&#xff0c;题目答案会根据我所学到的知识提供最优解。 &#x1f3e1;个人主页&am…...

HashMap ConcurrentHashMap介绍

目录 HashMap 数据结构 重要成员变量 Jdk7-扩容死锁分析 单线程扩容 多线程扩容 Jdk8-扩容 ConcurrentHashMap 数据结构 并发安全控制 源码原理分析 重要成员变量 协助扩容helpTransfer 扩容transfer 总结 CopyOnWrite机制 源码原理 HashMap 数据结构 数组…...

C++语法规则3(C++面向对象)

多态 C多态意味着调用成员函数时&#xff0c;会根据调用函数的对象的类型来执行不同的函数&#xff1b; 形成多态必须具备三个条件&#xff1a; 必须存在继承关系&#xff1b;继承关系必须有同名虚函数&#xff08;其中虚函数是在基类中使用关键字 virtual 声明的函数&#…...

Python tkinter 如何实现网站下载工具?将所有数据一键获取

前言 铁汁们有没有想过&#xff0c;如何把几个代码的功能结合到一起呢&#xff1f; 有想过的话&#xff0c;有没有实现过呢&#xff1f; 其实很简单的啊&#xff0c;咱就写一个界面就好了&#xff0c;想要哪个代码运行&#xff0c;鼠标轻轻一点就行 开发环境 python 3.8: 解…...

第六章:C语言数据结构与算法初阶之栈

系列文章目录 文章目录系列文章目录前言一、栈二、栈的实现三、接口函数的实现1、初始化2、销毁栈3、压栈与出栈4、判空5、元素个数6、返回栈顶元素四、栈中元素的访问总结前言 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 一、…...

Android学习之WebView

什么是WebView WebView是Android中UI组件的一种&#xff0c;WebView基于webkit内核&#xff0c;不过由于兼容性的原因在Android5.0后改为了Chromium内核。 WebView可以用来展示网页&#xff0c;常用于我们不想打开浏览器但又想浏览网页的情况。 WebView的使用 WebVeiw的常用…...

3/11 考试总结

时间安排 7:30–7:50 读题&#xff0c;T1 是个利用随机性的题目&#xff0c;T2 dp,T3 不知道是啥。 7:50–8:30 T1,对于随机有个结论时最值突变不超过 log &#xff0c;于是可以处理出所有 log 个区间然后统计答案&#xff0c;但这暴力做是个 3log 铁定过不去。 8:30–8:50 T2…...

Leetcode 141.环形链表 142环形链表II

141环形链表 文章目录快慢指针快慢指针 代码思路&#xff1a; slow 和fast 指向 head slow走一步&#xff0c;fast走两步 没有环&#xff1a; fast每次走2步 &#xff0c;如果 fast 最终遇到NULL(链表中的元素是 偶数)或者fast->next(链表中的元素是 奇数)遇到NULL&#xf…...

hibernate学习(五)

hibernate学习&#xff08;五&#xff09; hibernate的一对多关联映射&#xff1a; 一、数据库表与表之间关系 一对多建表原则&#xff1a; 多对多的建表原则&#xff1a; 一对一建表原则&#xff1a; &#xff08;1&#xff09;唯一外键对应&#xff1a; &#xff08;…...

STM32CubeIDE 快速开发入门指南

描述 STM32CubeIDE是一体式多操作系统开发工具&#xff0c;是STM32Cube软件生态系统的一部分。 STM32CubeIDE是一种高级C/C开发平台&#xff0c;具有STM32微控制器和微处理器的外设配置、代码生成、代码编译和调试功能。它基于Eclipse/CDT™框架和用于开发的GCC工具链&#xf…...

华为OD机试 - 火星文计算(C 语言解题)【独家】

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 使用说明本期题目:火星文计…...

超超超超保姆式详解——字符函数和字符串函数(学不会打我)上

目录 长度不受限制的字符串函数 strlen部分 strlen函数的易错小知识 strlen函数的实现 strcpy部分 strcat部分 自己实现strcat strstr函数部分 简单例子&#xff1a; 分析 strcmp部分 长度受限制的字符串函数 strncpy 简单例子 strncat strncmp 简单例子 &…...

Data mesh 笔记

有用的网站 https://www.datamesh-architecture.com/ https://www.agilelab.it/data-mesh-in-action https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/scenarios/cloud-scale-analytics/well-architected-framework https://www.datamesh-architecture.com…...

(八十三)大白话透彻研究通过explain命令得到的SQL执行计划(2)

今天我们就一步一步的来讲解不同的SQL语句的执行计划长什么样子&#xff0c;先来看第一条SQL语句&#xff0c;特别的简单&#xff0c;就是&#xff1a; explain select * from t1 就这么一个简单的SQL语句&#xff0c;那么假设他这个里面有大概几千条数据&#xff0c;此时执行计…...

案例18-面向对象之开门小例子

目录 一&#xff1a;背景介绍 二&#xff1a;思路&方案 1.面向过程 2.面向对象 3.面向对象(反射) 三&#xff1a;过程 1.面向过程&#xff1a;原本何老师的作用交给我了米老师来完成。 2.面向对象&#xff1a;把开门的方法完全交个何老师&#xff0c;米老师不需要有…...

【碎片化知识总结】三月第一周

目录 前言 1、开发中常用的 IDEA 编辑器&#xff0c;如何做到不用每次都重新配置&#xff1f; 2、如何使用 Python 获取视频文件信息&#xff1f; 3、使用 Java 的 try-with-resources 优化代码 4、使用 shell 脚本批量修改服务器某一目录下的文件后缀名称 5、MySQL优化&…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...