动态规划实例——01 背包详解

题目描述

有 n 件物品,每件物品有一个重量和一个价值,分别记为 w1,w2,…,wn 和 c1,c2,…,cn。现在有一个背包,其容量为 wk,要从 n 件物品种任取若干件。要求:(1)重量之和小于或等于 wk;(2)价值之和最大。

输入

共 3 行,第一行 2 个整数,表示 n 和 wk;第二行 n 个整数表示每一个物品的重量,第三行 n 个整数表示每一个物品的价值。

输出

一行一个整数,表示符合背包容量的最大价值。

样例

8 200
79 58 86 11 28 62 15 68
83 14 54 79 72 52 48 62

暴力枚举

我们以只有 A、B、C 三件物品的情况为例,对于每一个物品都存在不拿两种情况。以0表示不拿当前物品,以1表示拿当前物品,可以有如下分析结果。

可能上面的图看起来不够清晰,我们从左至右逐一列举出来观察,一眼就可以看出来规律。其实就是十进制的 0、1、2、3、4、…可枚举的最大值即 2n-1

000
001
010
011
100
101
110
111

根据上面的分析,我们可以写出如下代码。

#include<bits/stdc++.h>
using namespace std;int main()
{int n, wk;int w[10000], c[10000];cin>>n>>wk;for(int i = 0; i < n; i++){cin>>w[i];}for(int i = 0; i < n; i++){cin>>c[i];}int ans = 0;int max_val = 1 << n;// 逐一枚举for(int i = 0; i < max_val; i++){int ww = 0, cc = 0;int index = 0;// 转二进制int cur = i;while(cur){int bit = cur % 2;// 若拿第 index 个物品,则累加其重量和价值if(bit){ww += w[index];cc += c[index];}cur = cur >> 1;index++;}//计算最大值if(ww <= wk && ans < cc){ans = cc;}}//输出最大值cout<<ans<<endl;
}

递归求解

我们把背包容量为wk,有n个物品可以选择的问题表示为slove(wk, n)。那么在背包剩余容量可以装下第 n 个物品时,该问题可以表示为求如下两个问题的最大值

  • 选第 n 个物品:c[n-1] + slove(wk-w[n-1], n-1)
  • 不选第 n 个物品:slove(wk, n-1)

在背包剩余容量无法装下第 n 个物品时,问题直接变为

  • 不选第 n 个物品:slove(wk, n-1)

可以发现上述三个子问题可以继续向下拆分为规模更小,但类型一致的子子问题。于是可以写出如下递归求解代码。

#include<bits/stdc++.h>
using namespace std;int w[30]={0}, c[30]={0};// wk 背包剩余重量
// ch 可选项
int slove(int wk, int ch)
{if(wk <= 0 || ch <= 0){return 0;}// 若背包剩余容量无法装下 w[ch-1],则直接丢弃第 ch 个物品if(w[ch-1] > wk){return slove(wk, ch-1);}// 若背包剩余容量能装下 w[ch-1],则计算装和不装的最大值int a = c[ch-1] + slove(wk-w[ch-1],ch-1);int b = slove(wk, ch-1);return a > b ? a : b;
}int main()
{int n, wk;cin>>n>>wk;for(int i = 0; i < n; i++){cin>>w[i];}for(int i = 0; i < n; i++){cin>>c[i];}cout<<slove(wk, n);
}

动态规划

递归在执行过程中会存在重复计算相同子问题的情况,我们可以将其改为用循环实现,即动态规划的写法。dp[i][j]的含义即为:在背包容量为i,可选物品数量为j的情况下,符合背包容量的最大值。具体代码如下所示:

#include<bits/stdc++.h>
using namespace std;int w[30]={0}, c[30]={0};int main()
{int n, wk;cin>>n>>wk;for(int i = 0; i < n; i++){cin>>w[i];}for(int i = 0; i < n; i++){cin>>c[i];}int dp[1000001][21] = { 0 };for(int i = 1; i <= wk; i++) {for(int j = 1; j <= n; j++) {// 若背包剩余容量无法装下 w[j-1],则直接丢弃第 j 个物品if(w[j-1] > i) {dp[i][j] = dp[i][j-1];} else {// 若背包剩余容量能装下 w[j-1],则计算装和不装的最大值int a = c[j-1] + dp[i-w[j-1]][j-1];int b = dp[i][j-1];dp[i][j] = a > b ? a : b;}}}cout<<dp[wk][n];
}

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

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

相关文章

华为政企路由器产品集

产品类型产品型号产品说明 maintainProductA821 E_2*10GE/GE/FE(o)8*GE/FE(o)8*GE/FE(e),1*交流电源华为企业云端NetEngine A800 E综合业务一体化接入路由器是华为公司面向云时代推出的一款产品&#xff0c;用于企业快速接入网络&#xff0c;具备易部署、易运维、高性能、高…

ansible安装和常见模块

文章目录 ansible的安装1.1 yum install epel-release.noarch1.2配置epel源的baseurl1.3安装ansible1.4安装ansible报错问题1.5 yum卸载 ansible的安装 ansible是由epel源提供的&#xff0c;所以需要配置epel源。要么通过配置好的baseos源直接执行“yum install epel-release.…

华为机试练习题:HJ14 字符串排序

1、完整题目 HJ14 字符串排序 描述 给定 n 个字符串&#xff0c;请对 n 个字符串按照字典序排列。 数据范围&#xff1a; 1≤n≤1000 &#xff0c;字符串长度满足 1≤len≤100 输入描述&#xff1a; 输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度…

Modbus转Profinet网关在暖通空调系统中应用案例

在过去&#xff0c;空调系统一般采用传统的控制方式&#xff0c;通常需要使用独立的控制模块和传感器来监测和控制温度、湿度等参数。这种传统的控制方式不仅复杂&#xff0c;而且容易出现故障和误差&#xff0c;给用户的使用和维护带来了一定的困扰。 然而&#xff0c;通过P…

五、Linux命令执行绕过技巧

Linux命令执行绕过指的是&#xff0c;你在进行web测试&#xff0c;已经拿到了找到了执行linux命令的地方&#xff0c;但是有过滤&#xff0c;比如输入ls会被过滤掉&#xff0c;但是l\s可能就不会过滤&#xff08;l\s和ls一样同样能被执行&#xff09; 一、连接符绕过 1.单引号…

20.8 OpenSSL 套接字SSL传输文件

有了上面的基础那么传输文件的实现就变得简单了&#xff0c;在传输时通常我们需要打开文件&#xff0c;并每次读入1024个字节的数据包&#xff0c;通过SSL加密传输即可&#xff0c;此处的文件传输功能在原生套接字章节中也进行过详细讲解&#xff0c;此处我们还是使用原来的密钥…

Mysql8与mariadb的安装与常用设置

一、v10服务器mariadb的安装与常用设置 V10服务器默认安装了mariadb数据库。也可使用命令sudo yum install mariadb手动安装或升级默认安装的版本。 1.1 修改数据库密码 systemctl restart mariadb,重启mariadb服务&#xff1b;mysql -u root -p,要求输入密码直接回车&#…

微信小程序自动化采集方案

本文仅供学习交流&#xff0c;只提供关键思路不会给出完整代码&#xff0c;严禁用于非法用途&#xff0c;拒绝转载&#xff0c;若有侵权请联系我删除&#xff01; 一、引言 1、对于一些破解难度大&#xff0c;花费时间长的目标&#xff0c;我们可以先采用自动化点击触发请求&…

Bootstrap

一. 简介 使用版本: 建议使用v3版本 下载本地: 用于生产环境的 Bootstrap 使用CDN: 使用 BootCDN 提供的免费 CDN 加速服务 注意事项: 1. 只有下载到本地的pycharm中, 才会有提示. 2. 下载到本地: 含三个文件夹css 只有bootstrap.min.css和bootstrap.css生效, 其他可以…

centos7安装jdk-阿里云服务器

1.背景 2.安装步骤 步骤:(特别注意:虚拟机安装的一般是32位的操作系统,jdk也必须使用32位的) 查看虚拟机版本:sudo uname --m i686 //表示是32位 x86_64 // 表示是64位 查看是否已经安装jdk 看看 是否设置了jdk环境变量: echo $JAVA_HOME&#xff1b; 或运行命令&#xff1a; …

CMD命令行中如何切换路径。

问题描述&#xff1a; windows命令行中我记得切换命令是cd E:命令就行了呀。但是现在好像不行了。 问题解决&#xff1a;现在windows命令行中切换命令需要在cd E:之间增加一个/D。注意是/D&#xff0c;不是\D。 具体命令如下&#xff1a;CD /D E: 结果如下如所示&#xff1a…

Linux开发工具的使用(vim、gcc/g++ 、make/makefile)

文章目录 一 &#xff1a;vim1:vim基本概念2:vim的常用三种模式3:vim三种模式的相互转换4:vim命令模式下的命令集- 移动光标-删除文字-剪切/删除-复制-替换-撤销和恢复-跳转至指定行 5:vim底行模式下的命令集 二:gcc/g1:gcc/g的作用2:gcc/g的语法3:预处理4:编译5:汇编6:链接7:函…

Leetcode—2731.移动机器人【中等】

2023每日刷题&#xff08;二十二&#xff09; Leetcode—2731.移动机器人 算法思路 参考自灵茶山艾府 实现代码 class Solution { public:const int MOD 1e9 7;int sumDistance(vector<int>& nums, string s, int d) {int n nums.size();vector<long long…

Vue Vuex模块化编码

正常写vuex的index的时候如果数据太多很麻烦&#xff0c;如有的模块是管理用户信息或修改课程等这两个是不同一个种类的&#xff0c;如果代码太多会造成混乱&#xff0c;这时候可以使用模块化管理 原始写法 如果功能模块太多很乱 import Vue from vue import Vuex from vuex …

基于改进细化法的线激光中心提取方法

论文地址:Excellent-Paper-For-Daily-Reading/application/centerline at main 应用:应用——中心线 时间:2023/11/07 摘要 线激光条纹中心线提取的精度和速度是线激光三维测量技术的关键,针对现有的激光条纹中心提 取方法在速度快和精度高之间的矛盾,提出一种改进细化…

[JavaWeb]——JWT令牌技术,如何从获取JWT令牌

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、前言&#xff1a; 二、JWT令牌技术 2.1 概念介绍 2.2 组成介绍 2.3 JWT对象介绍 2.4 JWT生成 2.5 JWT校验 三、获取JWT令牌 四、总结 一、前言&#xff1a; 问题抛出❓ 许多网页都会设置登录界面&a…

Qt 继承QAbstractListModel实现自定义ListModel

1.简介 QAbstractListModel类提供了一个抽象模型&#xff0c;可以将其子类化以创建一维列表模型。 QAbstractListModel为将其数据表示为简单的非层次项目序列的模型提供了一个标准接口。它不直接使用&#xff0c;但必须进行子类化。 由于该模型提供了比QAbstractItemModel更…

ZZ308 物联网应用与服务赛题第B套

2023年全国职业院校技能大赛 中职组 物联网应用与服务 任 务 书 &#xff08;B卷&#xff09; 赛位号&#xff1a;______________ 竞赛须知 一、注意事项 1.检查硬件设备、电脑设备是否正常。检查竞赛所需的各项设备、软件和竞赛材料等&#xff1b; 2.竞赛任务中所使用的…

不完全考虑构造+dp与构造:1107T2

http://cplusoj.com/d/senior/p/SS231107B 发现reverse操作会对一堆数进行修改&#xff0c;但如果我们只关注其中一些数呢&#xff1f; 假设我们已经构造好 [ 1 , i − 1 ] [1,i-1] [1,i−1]&#xff0c;我们现在尝试构造 [ i , n ] [i,n] [i,n]&#xff0c;我们可操作的范…

JAVA中类和对象的认识

1、面向对象的初步认知 1.1 什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面 向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。用面向对象的…