01背包问题

背包,问题 · 浏览次数 : 7

小编点评

```c++ #include <iostream>#include <cstring>using namespace std;const int N = 1010, M = 1010;int n, V;int v[N], w[N];int dp[N][M];int main() {\tcin >> n >> V;\tfor (int i = 1; i <= n; ++ i ) cin >> v[i] >> w[i];\tfor (int i = 1; i <= n; ++ i ) \t\for (int j = 0; j <= V; ++ j ) \t\t\if (j >= v[i]) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);\t\t\telse dp[i][j] = dp[i - 1][j];\tcout << dp[n][V] << '\';\treturn 0;} 。归纳总结以上内容,生成内容时需要带简单的排版 ``` **代码说明:** 1. **状态表示**: `dp`数组用于记录在每个物品体积下,最多可以选取的最大价值。 2. **状态转移**: 对于每个物品,如果它的体积大于或等于其最大允许的体积,则可以从更小的物品中选取最大价值。 3. **边界条件**: 如果物品的体积大于或等于其最大允许的体积,则该物品可以被完全填充,其价值为其最大允许的价值。 4. **最终结果**: 最后结果存储在`dp[n][V]`中。

正文

题目

题目描述

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

i i i 件物品的体积是 v i v_i vi,价值是 w i w_i wi

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

输入格式

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

接下来有 N N N 行,每行两个整数 v _ i , w _ i v\_i, w\_i v_i,w_i,用空格隔开,分别表示第 i i i 件物品的体积和价值。

输出格式

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

数据范围

0 < N , V ≤ 1000 0 \lt N, V \le 1000 0<N,V1000
0 < v i , w i ≤ 1000 0\lt v_i, w_i \le 1000 0<vi,wi1000

输入样例

4 5
1 2
2 4
3 4
4 5

输出样例:

8

思路

我们用动态规划解决问题时需要经过如下几个步骤:

  1. 确定动态规划的状态表示,即 d p dp dp 数组所代表的含义。

  2. 根据第1步确定的状态表示来推想动态规划转移方程。

  3. 分析时间复杂度,如果复杂度不在我们允许的范围之内,尝试优化动态规划转移复杂度或重新定义状态表示。

对于这道01背包问题,我们执行以下步骤:

  1. d p [ i ] [ j ] dp[i][j] dp[i][j]表示在前 i i i 件物品里选出若干件,且物品体积和不超过 j j j 能取到物品的最大价值。若我们可以求解出 d p dp dp 数组,则 d p [ N ] [ V ] dp[N][V] dp[N][V] 就是我们要求的答案了。
  2. 考虑如何求得 d p [ i ] [ j ] dp[i][j] dp[i][j]。根据我们定义的状态, d p [ i ] [ j ] dp[i][j] dp[i][j] 表示在前 i i i 件物品中选取若干件体积和不超过 j j j 的最大价值,因此 d p [ i ] [ j ] dp[i][j] dp[i][j] d p [ i − 1 ] [   ] dp[i - 1][\ ] dp[i1][ ] 的差别只在于第 i i i 件物品在 d p [ i − 1 ] [   ] dp[i - 1][\ ] dp[i1][ ] 没被考虑,所以我们可以通过 d p [ i − 1 ] [   ] dp[i - 1][\ ] dp[i1][ ] 推出 d p [ i ] [ j ] dp[i][j] dp[i][j]
    接下来分别考虑第 i i i 件物品选或不选。
    如果我们选择第 i i i 件物品,那么从前 i − 1 i - 1 i1 种物品中选出的体积就不能超过 j − v i j - v_i jvi ,所能得到的最大价值为 d p [ i − 1 ] [ j − v i ] + w [ i ] dp[i - 1][j - v_i] + w[i] dp[i1][jvi]+w[i]
    若不选择第 i i i 件物品,则延续之前的最大价值,最大价值为 d p [ i − 1 [ [ j ] dp[i - 1[[j] dp[i1[[j]
    取这两种情况的最大值;因此,我们的状态转移方程为:
    d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − v i ] + w i ) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v_i] + w_i) dp[i][j]=max(dp[i1][j],dp[i1][jvi]+wi)
    注意:我们需要保证目前枚举到的 j j j 是大于等于当前物品体积的,否则说明现在的状态背包根本就装不下这个物品,只能延续之前的最大价值。
  3. 计算时间复杂度:我们不难发现,求解单个状态的复杂度仅为 O ( 1 ) O(1) O(1);所以总时间复杂度则为状态数 O ( N V ) O(NV) O(NV)

代码

#include <iostream>
#include <cstring>
using namespace std;
const int N = 1010, M = 1010;
int n, V;
int v[N], w[N];
int dp[N][M];
int main() {
	cin >> n >> V;
	for (int i = 1; i <= n; ++ i ) cin >> v[i] >> w[i];
	for (int i = 1; i <= n; ++ i ) 
		for (int j = 0; j <= V; ++ j ) 
			if (j >= v[i]) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
			else dp[i][j] = dp[i - 1][j];
	cout << dp[n][V] << '\n';
	return 0;
}

与01背包问题相似的内容:

01背包问题

题目 题目描述 有 N N N 件物品和一个容量是 V V V 的背包。每件物品只能使用一次。 第 i i i 件物品的体积是 v i v_i vi​,价值是 w i w_i wi​。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整

01背包问题的js解决方式

如果你有兴趣看这个相信你已经对背包问题有所了解,所以关于背包问题的描述,我就不写了。只记录一下自己对这个问题的一些看法和思考,于我而言,这个东西现在困扰我的是如何确定最优解。实质上关于背包问题网上的东西我大体都有看过,对于这个问题,常见的就是使背包重量动态增长,然后遍历每个要装入的这些包裹,当包裹的

LeetCode 周赛 350(2023/06/18)01 背包变型题

> **本文已收录到 [AndroidFamily](https://github.com/pengxurui/AndroidFamily),技术和职场问题,请关注公众号 [彭旭锐] 和 [BaguTree Pro] 知识星球提问。** - 往期回顾:[LeetCode 单周赛第 348 场 · 数

01.前后端分离中台框架后端 Admin.Core 学习-介绍与配置说明

## 中台框架后端项目 Admin.Core 的介绍与配置说明 > 中台admin是前后端分离权限管理系统,Admin.Core为后端项目,基于.NET 7.0开发。 > 支持多租户、数据权限、动态 Api、任务调度、OSS 文件上传、滑块拼图验证、多数据库,分布式缓存、分布式事务等 - 接口文档一

[转帖]01-rsync备份方式

https://developer.aliyun.com/article/885783?spm=a2c6h.24874632.expert-profile.284.7c46cfe9h5DxWK 简介: Rsync备份方式 1.rsync概述 rsync是一款开源的备份工具,可以在不同主机之间进行同步

【PB案例学习笔记】-01创建应用、窗口与控件

写在前面 这是PB案例学习笔记系列文章的第一篇,也是最基础的一篇。后续文章中【创建程序基本框架】部分操作都跟这篇文章一样, 将不再重复。该系列文章是针对具有一定PB基础的读者,通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证 小伙伴们能应付公司的各种开发需求。 文章中设计到的源码,小凡都上

[转帖]Redis 运维实战 第01期:Redis 复制

https://cloud.tencent.com/developer/article/1986816 作者简介 马听,多年 DBA 实战经验,对 MySQL、 Redis、ClickHouse 等数据库有一定了解,专栏《一线数据库工程师带你深入理解 MySQL》作者。 从这篇文章开始,将出几期 R

[转帖]RabbitMQ学习笔记01:初识与安装

https://www.cnblogs.com/alongdidi/p/rabbitmq_overview.html 原作者写的真好. 前言 本人是一名运维工程师,在此公司接触到 RabbitMQ ,平时针对此软件的工作内容就是集群的安装以及配置监控等,对其的理解也仅仅是知道其是一种消息队列的服务,

[转帖]【shell语法 | 01】基础练习

https://www.cnblogs.com/sunbines/p/14587095.html 目录 利用判断符号[ ] 循环体 正文 回到顶部 利用判断符号[ ] [ str ] : str 字符串存在为真 1 [root@localhost ~]# if [ ]; then echo 'tru

[转帖]jmeter正则表达式应用-01篇

如图所示 1.先新建一个login的http请求,然后再login的请求下新增一个正则表达式提取器,增加一个查看结果树查看结果 假如后端接口返回的数据为"{'msg': 'login success', 'code': 1001, 'token': '48b2837a33461f58988ae72b