首页 > 其他分享 >【经典问题】精析:一文搞懂 动态规划解决 0-1背包问题

【经典问题】精析:一文搞懂 动态规划解决 0-1背包问题

时间:2024-07-25 18:28:55浏览次数:14  
标签:arr 背包 容量 精析 int 物品 搞懂 size

背包问题核心元素:

数量为n的物品,容量为size的背包,给出每个物品的重量weight和价值val,求背包能装的物品最大总价值。

求解思路的本质:

从小体量(少物品,少容量)的问题开始,不断求出局部最优解,然后以此为基础放大问题(求得较多物品,较大容量下最优解)

重复上述过程,直到求出题目要求的最优解(数量为n的物品,容量为size的背包条件下的)

//一下子无法理解没关系哈,接着往下看,时不时回来对照着看看这总结

概念意义的解析:

核心工具,在于我们自己初始化的一个二维数组

int arr[obj_num+1][bag_size+1] = {0};//所有元素均初始化为0

// 第 i 行:第 i 种物品 (其中物品从下标为1开始放,第 0 行全部初始化为0

// 第 j 列:背包容量为 j 

// 第 i 行 第 j 列数组的值(即arr[ i ][ j ])相当于上文提到的 “小体量背包问题  :数量为n=i 的物品,容量为size=j 的背包,给出每个物品的重量weight和价值val,求背包能装的物品最大总价值。”的最优解

具体实现操作

为表述简介,记X = 该行对应物品

初始化:第0行全部初始化为0(可理解为,没有物品,背包容量再大也装不出任何价值)

接着,从第一行开始,逐行从左往右地遍历,在对arr[ i ][ j ]赋值前,做如下判断:

X能否装进空背包中(weight[i-1] <= j)//说明:weight数组第 i 个物品的下标为 i-1

0.若不能,则问题转化为: 求数量为 n = i-1 的物品(不考虑X),容量为size=j 的背包的最优解 :

if(wei[i-1] > bag_size)
{
	arr[i][j] = arr[i-1][j]; continue;
} 

1.若能放进背包,那咱们就要比较第 i 种物品 放进背包&不放进背包 两种情况下的获利

        1.0不放进背包:跟上面一样,就是求数量为 n = i-1 的物品(不考虑当前行对应物品),容量为size=j 的背包的最优解 arr[i-1][j]。

        1.1放进背包,那么总最优价值就是: 该物品价值 + 数量为 n = i-1 的物品(不考虑当前行对应物品),容量为size=j - weight[ i-1 ] 的背包的最优解 arr[i-1][ j-weight[ i-1 ]]

arr[i][j] = max(arr[i-1][j], arr[i-1][j-wei[i-1]] + val[i-1]);

重复上述过程,最终求得的二维数组最右下角的值 arr[n][size] 就是数量为n的物品,容量为size的背包的最优解

总体代码见下(C++):

#include<bits/stdc++.h>
using namespace std;
#define obj_num 5
#define bag_size 7
int main()
{
	int wei[obj_num] = {1, 2, 4, 6, 8};//物品重量
	int val[obj_num] = {4, 2, 1, 7, 5};//物品价值
	int arr[obj_num+1][bag_size+1] = {0};//所有元素均初始化为0
	
	for(int i = 0; i<=obj_num; i++ )
	{
		for(int j = 0; j<=bag_size; j++)
		{
			if(i == 0) continue;//第0行全是0
			if(wei[i-1] > bag_size)
			{
				arr[i][j] = arr[i-1][j]; continue;
			} 
			arr[i][j] = max(arr[i-1][j], arr[i-1][j-wei[i-1]] + val[i-1]);
		}
	}
	//打印arr
	for(int i=0; i<=obj_num; i++)
	{
		for(int j=0; j<=bag_size; j++) cout<<arr[i][j]<<" ";
		cout<<endl;
	}
	//
	cout<<"所求结果为:"<<arr[obj_num][bag_size];
	return 0;
}

~希望对你有帮助~

标签:arr,背包,容量,精析,int,物品,搞懂,size
From: https://blog.csdn.net/H13420972436/article/details/140667200

相关文章

  • 一文搞懂系列——PEM文件解析流程
    背景前几周,协助同事解决了SM2软签名的需求,其流程可参考终于解决了!!!基于GmSSL的SM2签名算法及思路分享。但是在解决这个问题的过程中,让我想起了一些不好的回忆:曾经在大众项目中,也接触过椭圆曲线算法签名。其中因为平台下发的公钥格式,由于双方理解不一致,导致最终调试很久,并......
  • 【Git-驯化】一文搞懂git中代码回测reset详细使用方法
    【Git-驯化】一文搞懂git中代码回测reset详细使用方法 本次修炼方法请往下查看......
  • C++语法10:C++实现0-1背包问题的动态规划解法
    动态规划(DynamicProgramming):解锁复杂问题的钥匙在算法设计与分析的广阔领域中,动态规划(DynamicProgramming,DP)无疑是一把锋利的剑,用于斩断复杂问题中缠绕的荆棘。它通过将大问题分解为小问题,并存储子问题的解来避免重复计算,从而高效地解决了一系列看似无解的难题。本文将从......
  • 代码随想录算法训练营第41天 |322.零钱兑换、279.完全平方数、139.单词拆分、多重背包
    322.零钱兑换https://leetcode.cn/problems/coin-change/description/代码随想录https://programmercarl.com/0322.零钱兑换.html#算法公开课279.完全平方数https://leetcode.cn/problems/perfect-squares/description/代码随想录https://programmercarl.com/0279.完全平......
  • 代码随想录算法训练营第40天 | 完全背包问题:完全背包基础理论、518.零钱兑换II、377.
    完全背包基础理论https://programmercarl.com/背包问题理论基础完全背包.html#其他语言版本卡码网完全背包例题https://kamacoder.com/problempage.php?pid=1052518.零钱兑换IIhttps://leetcode.cn/problems/coin-change-ii/description/代码随想录https://programmercarl......
  • # 代码随想录算法训练营第38天 | 01背包问题:1049.最后一块石头的重量II(最多能装多少)、
    1049.最后一块石头的重量IIhttps://leetcode.cn/problems/last-stone-weight-ii/代码随想录https://programmercarl.com/1049.最后一块石头的重量II.html#算法公开课494.目标和https://leetcode.cn/problems/target-sum/description/代码随想录https://programmercarl.com......
  • 转 | 一次搞懂数据大屏适配方案 (vw vh、rem、scale)
    https://juejin.cn/post/7163932925955112996  一次搞懂数据大屏适配方案(vwvh、rem、scale)懒惰的智慧2022-11-0956,229阅读11分钟 前言当接到可视化大屏需求时,你是否会有以下疑问......
  • 背包问题的一道经典问题
    ProblemDescription小A有\(n\)次获得星星的机会。在第\(i\)次机会里他有如下的\(5\)种选择(他必须做出恰好一种选择):跳过这一轮。\(a_i\)的代价获得\(1\)颗星星。\(b_i\)的代价获得\(2\)颗星星。\(c_i\)的代价获得\(3\)颗星星。\(d_i\)的代价获......
  • 有限背包计数问题
    https://class.51nod.com/Html/Textbook/ChapterIndex.html#chapterId=335&textbookId=126https://class.51nod.com/Html/Challenge/Problem.Html#problemId=1597如有限背包计数问题发现对于物品\(i\)最多填充\(i*i\),而对于\(i>\sqrtn\)可以视为完全背包,所以我们分为两类......
  • 一文搞懂Java中的双亲委派
    一天正在宿舍里忙着写代码。突然,老师给我布置了一项新任务:优化他正在开发的项目中的类加载机制。我对类加载器了解不多,开始翻阅各种资料,逐渐了解了Java中的类加载器机制。尤其是当读到双亲委派模型时,脑海中豁然开朗。仿佛看到了类加载请求在层层递进、逐步传递的画面,像极了树状......