全面理解动态规划的背包问题

动态规划之0-1背包问题(容易理解,附公式及python代码) 0-1 背包问题描述: 给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi 。应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大? 注:不能选择装入某物品的一部分,也不能装入同一物品多次 阅读详情

引言:

背包问题始终贯穿着学习算法的全过程,学会并且能够学以致用背包问题尤为重要。

问题描述:

给定n个物品的重量及效益,给定背包的容量。求背包能装的最大效益值,及最大效益值时装入背包的物品编号。

题解:

dp[i][j] i表示考虑前i个物品,j代表当前背包的容量为j。所以如果当前背包不能装下第i个物品,那么dp[i][j]=dp[i-1][j],说明背包容量为j时,考虑前i个物品和考虑前i-1个物品的最大效益值相同(因为当前背包装不下第i个物品),反之,如果当前背包能装下第i个物品,那么就要考虑要不要装入物品i(即装入物品i会不会是背包的最大效益值增加)。如果wealth[i-1]+dp[i-1][j-weight[i-1]]大于dp[i-1][j],说明装入该物品能使背包的效益值变大,则装入该物品;反之则装入该物品不能是背包的效益值变大,所以就不装该物品。由此递推,则dp[dp.size()-1][dp[0].size()-1]就是当前背包容量为dp[0].size()-1,考虑前dp.size()-1个物品的背包最大效益值。

要想知道该物品是否在背包效益值最大的时候装入背包,就要明白上面的递推公式,如果该物品没装入背包,则dp[i][j]=dp[i-1][j],反之,则该物品装入背包。然后再缩小背包容量或物品考虑的规模(即前n个物品,逐步缩小n),直到n=0或背包的剩余容量为0.

代码:

#include<iostream>
#include<vector>
using namespace std;
/*
物品的重量下标从0开始,即weight[0]是编号为1物品的重量
物品的效益下标从0开始,即wealth[0]是编号为1物品的效益
*/
int Max(int a,int b)
{
	return a>b?a:b;
}
int max_benefit(vector<vector<int> > &dp,vector<int> weight,vector<int> wealth)//找到最大效益值 
{
	int i,j;
	for(i=0;i<dp.size();i++)
	{
		for(j=0;j<dp[0].size();j++)
		{
			if(i==0||j==0)
			{
				dp[i][j]=0;
				cout<<dp[i][j]<<"\t";
				continue;
			}
			int max=0;
			if(j<weight[i-1])//容量为j不能装下第i个物品 
			{
				dp[i][j]=dp[i-1][j]; 
			}
			else
			{
				dp[i][j]=Max(dp[i-1][j],wealth[i-1]+dp[i-1][j-weight[i-1]]);
			}
			cout<<dp[i][j]<<"\t";
		}
		cout<<endl;
	}
	return dp[dp.size()-1][dp[0].size()-1]; 
}
vector<int> Find(vector<vector<int> > dp,vector<int> weight)//找到最大效益值时物品的编号 
{
	int i,j;
	vector<int> res;
	i=dp.size()-1;
	j=dp[0].size()-1; 
	while(i>0&&j>0)
	{
		if(dp[i][j]!=dp[i-1][j])//编号i的物品在背包里 
		{
			res.push_back(i);
			j=j-weight[i-1]; 
			i=i-1;
		}
		else
		{
			i--;
		}
	}
	return res;	
}
int main()
{
	int n,i,j,capacity;
	cout<<"请输入物品的数量"<<endl;
	cin>>n;
	cout<<"请输入背包的容量"<<endl;
	cin>>capacity; 
	vector<int> weight(n);
	vector<int> wealth(n);
	vector<int> res;
	cout<<"请输入n个物品的重量"<<endl;
	for(i=0;i<n;i++)
	{
		cin>>weight[i];
	}
	cout<<"请输入n个物品的价值"<<endl;
	for(i=0;i<n;i++)
	{
		cin>>wealth[i];
	}
	vector<vector<int> > dp;
	for(i=0;i<n+1;i++)
	{
		vector<int> temp(capacity+1,0);
		dp.push_back(temp);
	}
	cout<<"最大的效益是"<<max_benefit(dp,weight,wealth)<<endl;
	res=Find(dp,weight);
	cout<<"最大效益值时装入物品的编号"<<endl; 
	for(i=res.size()-1;i>=0;i--)
	{
		cout<<res[i]<<"\t";
	}
	cout<<endl;
	return 0;
}

结果展示:

在这里插入图片描述
在这里插入图片描述

推荐练习题目:

背包问题1
背包问题2
背包问题3
背包问题4

【动态规划算法 01背包问题 图解+画表】简单理解 图解+表 理解动态规划算法 1、动态规划算法的思想 将大问题划分为小问题进行解决,从而一步步获取最优的处理办法 动态算法和分治算法类似,基本都是将求解的问题,我们先分为子问题,先求解子问题的解,然后从这些子问题的解得到原问题的解 与分治算法不同的是,适用于动态规的问题,经分解得到的子问题往往不是互相独立的,及就是下一个子问题的解是建立在上一个子阶段的基础上,进一步进行求解 动态规划可以通过填表的方式来逐步的推进 说了这么多,不如举个栗子实在,上题 2、01背包问题 01背包问题是动态规划算法的一个出. 阅读详情

相关推荐

背包问题(最大收益分枝定界法)

非常有用的背包问题最大收益分枝定界算法,计算机老师强烈推荐。

算法设计与分析:多重背包问题

问题描述 给定n个物体(它们的重量为:w1,w2,…,wn,价值为:v1,v2,…,vn) 和 一个承受重量为W的背包,每个物品有n件,问怎么选取这些物体,放在背包中(不超过背包的承重),让所取的子集达到最大价值 解析思路 在0-1背包基础上,即递推每一个物品放置之前和放置之后价值的对比的前提下,物品数量限制k变为n 递推式 F( i , j )=max{ F ( i-1 , j-k* wi ) + k* wi } 0<= k< ni; i = [0 , n] j = [0 , w] F(i

qq_45038855的博客 1782

LabVIEW机器视觉通用软件

LabVIEW 通用视觉一款仿C模式的思想与方法 全网最精简零基础+通用视觉全套视频教程 只想把LabVIEW当作一种兴趣,结果却当成了职业 http://t.elecfans.com/c1181.html 本次(开源 )针对有一定视觉基础或项目开发经验的工程师量身打造视觉通用性系统(完全仿面向对象的原理),相对于一般的非标框架更具功能性,有效的解决复杂项目开发过程中的思路瓶颈。 LabVIEW通用视觉系统:通用软件可快速解决大部分简单的视觉开发项目,帮助众多软件工程师解决在非标视觉软件开发中的繁琐过程问

qq_21516871的博客 4610

01背包问题和完全背包问题,一个不理解的关键。

01背包问题 题目 有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是: f[i][v]=max{f[i-1][v],f[i-

Shuuki 1235

RLHF的数学表示

RLHF(Reinforcement Learning with Human Feedback)是一种结合了强化学习和人类反馈的机器学习方法。它通常用于训练智能体(agent)在复杂环境中做出决策,同时利用人类的反馈来指导和改进学习过程。RLHF 没有一个统一的数学表示式,因为它依赖于具体的应用场景和实现细节。然而,我们可以从强化学习和人类反馈的角度来描述RLHF的一些关键数学概念。

xw555666的博客 689

基于aarch64分析kernel源码 六:kernel_init进程(1号进程)、kthreadd进程(2号进程)

kernel_init进程(1号进程)、kthreadd进程(2号进程)分析

OnlyLove_的博客 765

Qt6 + OpenGL实战:手把手教你打造一个可交互的3D动态曲线可视化工具

本文详细介绍了如何使用Qt6和OpenGL构建一个高交互性的3D动态曲线可视化工具。通过实战教程,读者将学习到从环境配置、三维坐标系绘制到动态曲线数据管理的全过程,包括鼠标交互控制、实时数据更新等关键功能的实现,以及性能优化技巧,适用于工业监控和科学计算等领域。

weixin_30733003的博客 241

CloudCompare 二次开发(35)——提取多条直线

使用CloudCompare与PCL编程实现的多条空间直线的提取。

点云侠的博客 440

背包问题总结

前面是转载来的背包9讲,非常详细,后面有几个lintcode上的题目 前言 本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容是写作一份较为完善的NOIP难度的动态规划总结,名为《解动态规划题的基本思考方式》。现在你看到的是这个写作计划最先发布的一部分。 背包问题是一个经典的动态规划模型。它既简单形象容易理解,又在某种程度上能够揭示动态规划的本质,故不少...

William Zhao's notes 2万+

Android Input——输入系统介绍(一)

Input 系统对于提供流畅、灵敏和一致的用户交互体验至关重要,它需要在不同的设备、场景和应用中保证输入事件的正确性、及时性和安全性。Android 输入系统是一个复杂但高效的设计,旨在处理来自各种输入设备(如触摸屏、键盘等)的用户交互,并将这些交互转换为应用程序可以理解和响应的形式。EventHub:输入系统的最底层,直接与硬件通信,监听和读取输入设备的原始事件。:从 EventHub 获取原始输入事件,对其进行解析,转化为更高层次的事件,以便上层应用或服务能够理解。

小旭的专栏 1713

利用蓝牙低功耗技术与位置数据,提升邮政运输工具及笼车追踪的效率

BLE 即蓝牙低功耗技术,与无线音箱或各类电脑配件所用的技术类似。正如其名,BLE 的特点是:在实现相近传输范围的同时,功耗显著更低。这让它能应用于对电池续航要求极高的场景。

专业开发者的博客,一个从事Android WiFi和蓝牙的工程师 779

0/1背包问题与最大收益

池塘的水满了,雨也停了,田边的稀泥里到处是泥鳅。 不过,今天不捉泥鳅,而是去捉螃蟹,待会儿太阳小点就出发。拿个袋子,当然是捉得越多越好,于是想到类似的经典问题: 小偷夜入宝地,可偷宝贝甚多,然背包承重有限,最大收益几何? 这是一个典型的0/1背包问题,为什么叫0/1背包问题呢?因为对于一件宝贝,小偷要么选择偷它,要么选择不偷它。小偷陷入了左右为难的境地,我们对小偷的困难进行分析和具体化。 ...

认知 行动 坚持 2879

优秀的 Verilog/FPGA开源项目介绍(一)-PCIe通信

优秀的 Verilog/FPGA开源项目介绍(一)-PCIe通信今天开始会陆续介绍一些优秀的开源项目,项目基本都是和FPGA或HDL相关的。对于一些找工作或者急需项目经验的人来说,这些项目...

OpenFPGA的博客 8118

从01背包问题理解动态规划

原文地址:http://www.cnblogs.com/xy-kidult/archive/2013/03/25/2970313.html 01背包问题具体例子:假设现有容量10kg的背包,另外有3个物品,分别为a1,a2,a3。物品a1重量为3kg,价值为4;物品a2重量为4kg,价值为5;物品a3重量为5kg,价值为6。将哪些物品放入背包可使得背包中的总价值最大?   

zr459927180的博客 835

准备生日礼物

摘要: 题目要求统计某月份需要准备的员工生日礼物数量。输入包括目标月份、员工姓名列表和对应的生日列表(格式为Year/Month/Day)。需处理重复员工(以最后一次录入为准),统计该月生日的员工人数。示例1中5月有3名员工生日,输出3;示例2中10月有6名,输出6。解题关键在于使用哈希表去重(以员工姓名为键),拆分生日字符串提取月份进行匹配。代码实现(C++/Java/Python)均遵循以下步骤:读取输入、哈希去重、解析月份并统计目标月份人数。时间复杂度为O(n),空间复杂度O(n)。

面试高手的博客 300

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

动态规划之01背包问题(最易理解的讲解)

01背包问题,是用来介绍动态规划算法最经典的例子,网上关于01背包问题的讲解也很多,我写这篇文章力争做到用最简单的方式,最少的公式把01背包问题讲解透彻。 01背包的状态转换方程f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] } f[i,j]表示在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的最大价值。 Pi...

a490488213的博客 290

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

菜鸡acmer理解 【动态规划】01背包问题

下定决心,这次总结完一定要深刻理解,不能再学了忘忘了学了。。。。。。 01背包问题描述 有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和? 大体思路如下: 根据动态规划解题的步骤:问题抽象 -> 建立模型 ->寻找约束条件 ->判断是否满足最优性原理 -> 找大问题与小问题的递推关系式(最重要) -> 填表(模拟试一下)...

Aetherrrr的博客 519

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

动态规划--背包问题的另一种通俗理解(C++)

动态规划的入门可以先看这篇文章:动态规划入门 背包问题是动态规划中最经典的一个问题,要是比较难的一个问题。 题目: 有一个背包,它的容量为C(Capacity),现在有n种不同的物品,编号为0…n-1,其中每一件物品的重量为w(i),价值为v(i)。问可以向这个背包中盛放哪些物品,使得在不超过背包容量的基础上,物品的总价值最大。 题目解析: 变量: C(容量) i(第i个物品) w(i) (第i件物品的重量) v(i)(第i件物品的价值) 要求: (1) w(0)+w(1)+…w(i-1)<=C

weixin_45479946的博客 478

【动态规划】01背包问题(配合视频与代码理解,超详细)

01背包,动态规划,算法,c++

Aa_Lyang的博客 898

动态规划之01背包问题(最易理解的讲解)(转载)

动态规划之01背包问题(最易理解的讲解)(转载)http://blog.youkuaiyun.com/mu399/article/details/7722810点击打开链接

xifengcode 501

理解动态规划——01背包问题

1. 概述 01背包问题是很经典的动态规划问题。它的核心便是一个最大化公式 其中f(i, j)前面i个商品在背包容量为j的情况下达到的最大的价值;weight[i]是第i件商品的重量;prize[i]是商品的价值。也就是在现在这个背包大小情况下在选择还是不选择当前商品中求取总价值最大化。本文中使用较为经典的方式(使用中间表)来解决该问题。 这是本文中测试数据得到的中间表:

m_buddy的博客 935

01背包问题和完全背包问题(动态规划的理解)

理解上述要点,那么动态规划的核心电就在于两个。

choose_heart的博客 739

关于背包问题动态规划代码的理解和应用

关于背包问题动态规划代码的理解和应用—— 首先,关于背包问题动态规划的详细讲解在https://v.youku.com/v_show/id_XMTQ3MzI0NzI2OA==.html这个视频链接有详细的介绍,在此引用某位大神制作的视频表示感谢,同时也说声抱歉在我的博客引用视频没有直接取得同意。关于视频中那个外国的网页也给上https://www.merlot.org/merlot/viewMat...

关于背包问题动态规划代码的理解和应用—— 753

动态规划总结(背包问题的深入理解)

有这样两道题: 1. 有一段楼梯有n级台阶,规定每一步只能跨一级或两级,要登上第n级台阶有多少种不同的走法? f[i]=sum{ f [ i - c[j] ] }其中c[j]为题目明确告知的可能性选择(在这里可以认为c[0]=1,c[1]=2),用于内循环(如果规定每一步能跨) i - c[j] 就是状态,它转移到状态i有c[j] 数组元素个数个可能性。 即i可由i - c[j] 转移而来

zhuma的编程学习 1509
上一篇: 约瑟夫环问题即多种解法
下一篇: 动态规划及其动态规划经典例题
追梦少年ML
博客等级 码龄7年 36粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值