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

151、【动态规划】AcWing ——2. 01背包问题:二维数组+一维数组(C++版本)

题目描述

在这里插入图片描述
在这里插入图片描述
原题链接:2. 01背包问题

解题思路

(1)二维dp数组

动态规划五步曲:

(1)dp[i][j]的含义: 容量为j时,从物品1-物品i中取物品,可达到的最大价值

(2)递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]),其中dp[i - 1][j]表示不放物品i时的最大价值;j - v[i]表示给物品i留出空间,dp[i - 1][j - v[i]]表示给物品i留出空间后,放入其余物品可达到的最大价值(由于是按物品递增顺序遍历,因此为从1-i-1的物品),dp[i - 1][j - v[i]] + w[i]表示放入物品i和其余放入其余物品,可到达的最大价值。

(3)dp数组初始化: dp[0][j] = d[i][0] = 0, dp[0][j]中j >= v[i]的取w[i]

(4)遍历顺序: 从小到大,先背包后物品,或先物品后背包都可以。

(5)举例: **加粗样式**

#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;const int N = 1010;
int dp[N][N];int main(){int n, m;int v[N], w[N];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 = 1; j <= m; j++) {// 当前物品重量大于背包容量时,不放该物品if(j < v[i])        dp[i][j] = dp[i - 1][j];// 当前物品重量小于等于背包容量时,在放该物品后和不放该物品之间选择一个最大价值else                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);}}cout << dp[n][m] << endl;return 0;
}

(2)优化为一维dp数组(滚动数组)

滚动数组含义:本轮所计算的数,需要用到上一轮的结果,依次类推,滚动计算。

优化成一维那就要在遍历上实现与二维相同的逻辑顺序,从而实现仅用一维就可以代替二维。

动态规划五步曲:

(1)dp[j]数组的含义: 容量为j时,装入的物品可达到的最大价值。

(2)递推公式: dp[j] = max(dp[j], dp[j - v[i]])

(3)dp数组初始化: dp[0] = 0

(4)遍历顺序: 两层for循环,先遍历物品,再遍历背包,内层按背包从大到小递减顺序遍历。
如果删除dp中的维度[i]后,还保持对j的从小到大遍历,那么此时的代码其实是等价于dp[i][j] = max(dp[i][j - 1], dp[i][j - v[i]),在一遍后续遍历中,因为j是从小到大与v[i]相减,在后续相减时,可能会出现本轮遍历中用过的数,会使之前使用过的数重复相加。

而如果以对j进行从大到小遍历,因为此时是j是从mv[i],以此顺序计算dp[j - v[i]]时,在一遍后续遍历中,都是会基于上一轮对i的遍历而进行判定,并且由于j变化而v[i]不变,在后续不会出现使用过的数重复相加。每次遍历到的j所对应dp[j - v[i]]都还没有被更新,就相当于是之前的状态dp[i - 1][j - v[i]],从而得到dp[j] = dp[j - v[i]]就等价于dp[i][j] = dp[i - 1][j - v[i]]

(5)举例: 在这里插入图片描述

#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;const int N = 1010;
int dp[N];int main(){int n, m;int v[N], w[N];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--) {dp[j] = max(dp[j], dp[j - v[i]] + w[i]);}}cout << dp[m] << endl;return 0;
}

参考文章:AcWing 2. 01背包问题(状态转移方程讲解) 、AcWing 2. 01背包问题 、动态规划:关于01背包问题,你该了解这些!(滚动数组)

http://www.lryc.cn/news/2198.html

相关文章:

  • DS期末复习卷(二)
  • 大数据技术架构(组件)31——Spark:Optimize--->JVM On Compute
  • ETL基础概念及要求详解
  • 刷题记录:牛客NC23054华华开始学信息学 线段树+分块
  • 二叉搜索树(查找,插入,删除)
  • C# PictureEdit 加载图片
  • 3种方法设置PDF“打开密码”,总有一种适合你
  • 第三章 数据链路层(点到点的传输服务)-计算机网络(笔记)
  • volatile关键字与CAS机制
  • LeetCode题解 动态规划(四):416 分割等和子集;1049 最后一块石头的重量 II
  • 【FFMPEG源码分析】从ffplay源码摸清ffmpeg框架(二)
  • PCIE 学习笔记(入门简介)
  • 锁的优化机制了解嘛?请进!
  • 5.点赞功能 Redis
  • Java序列化和反序列化(详解)
  • 【刷题篇】链表(上)
  • ConcurrentHashMap设计思路
  • Unity基于GraphView的行为树编辑器
  • 网络流量传输MTU解析
  • 30个HTML+CSS前端开发案例(四)
  • 《TPM原理及应用指南》学习 —— TPM执行环境3
  • 实验名称:经典同步问题:生成者与消费者问题
  • EasyCVR视频云存储的架构解析与Sharelist云存挂载方法介绍
  • 电机参数中力矩单位kgf.cm,Nm,mNm表示的含义
  • 使用scikit-learn为PyTorch 模型进行超参数网格搜索
  • Windeployqt 打包,缺少dll 的解决方法
  • 第四章:搭建Windows server AD域和树域
  • 【解决方案】老旧小区升级改造,视频智能化能力如何提升居民安全感?
  • 【遇见青山】项目难点:缓存穿透的解决方案
  • 单一职责原则|SOLID as a rock