01背包问题(不可分割型)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_44116998/article/details/102231861

题目描述
有 N 件物品和一个容量为 V 的背包。第 i 件物品的体积是 c [ i ],价值是 w [ i ] 。求解将哪些物品装入背包可使价值总和最大。


思路分析
这个是一个很老的问题了,很多人应该知道了,就不那么详细的介绍了。
这个问题,我们可以这样思考,一开始比如给当一个背包的空间是 10,我们仅有的物品的个数是 5 个,满足(value,weight):{(1 , 2 ), ( 2 , 3),( 3 , 2),(1 , 4 ), ( 3 , 1)};并且包裹的最大容量是6;

  1. 那么按照正常的方式,我们一开始看作只有物品一号存在(1 , 2 ),那么当包裹容量为 2 时,可以放入背包的,并且随着包裹容量为 3,4,5,依次递增到 6,我们会发现此时肯定都是满足要求的,将数组ExcelFunction[1][2 到 6]都赋值价值为 1,而ExcelFunction[1][1] = 0,因为放不进去。
  2. 不废话,接着下一个二号物品:此时随着容量达到 3 的时候,可以放进背包,但是此时我们会想 比起之前放入的那一个一号物品,当时价值为 1,此时又放入二号物品,价值会增加吗?比较之下会发现,若总价值比原来大,此时,数组处理是ExcelFunction[2][3] = ExcelFunction[ 1 ][ 1 ] + value [ 2 ];这个操作相当于将第 i 号物品拿进去的操作。如果不满足,那么继承前一个的价值ExcelFunction[i][j] = ExcelFunction[i - 1][j],即可。后面一样的处理即可。

公式略解
但是呢,那个公式我觉得有必要记录一下,我理解的挺有一会儿的,烦:
第一个公式:
ExcelFunction[ i ][ j ] = ExcelFunction[i - 1][ j ];

  • 上面这个公式我理解起来挺简单的,就是在相同背包容量的情况下,后者因为背包暂时虚设的容量不够大而只有延续之前的背包内物品的价值。
  • 比如放置第1个物品后,某时虚设的背包容量为1,价值为4,公式为ExcelFunction[1][ 1 ] = 4;等到放置第二个物品(value = 2,weight = 2)的时候,由于weight = 2 大于 1(此时的虚设背包容量),那么很显然放不进去,只能将ExcelFunction[ 2 ][ 1 ] = ExcelFunction[1][ 1 ] = 4。

第二个公式:
ExcelFunction[ i ][ j ] = max( ExcelFunction[ i - 1 ][ j - weight[ i ] ] + value[ i ], ExcelFunction[i - 1][ j] );

  • 而这个公式呢,接着刚才的分析,虚设的背包容量递增到 j = 2时,j >= weight(weight = 2),那么我们可以利用这个公式实现,首先ExcelFunction[ 1 ][ 2 ] = 4,这是放置第一个物品赋的值,那么我们等到此时有将第二个物品放进背包的机会,那么就两种选择:放 or 不放?
  • 如果不放,那么 值为ExcelFunction[1][ 2 ] = 4为4;
  • 如果放了,那么ExcelFunction[2][ 2 ] = ExcelFunction[1][ 2 - 2 ] + value(value = 2) = 2,显然应该不放,就取前一个不放的值( 4 );
    这就是这个公式的差不多意思吧。

代码实现

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
constexpr auto Maxsize = 1000;
int  totalweight = 0, num = 0;//总重量,包裹数
int ExcelFunction[Maxsize][Maxsize];
int parent[Maxsize];
int DP(int value[], int weight[])
{
	for (int i = 1; i <= num; i++)
		for (int j = 1; j <= totalweight; j++)
		{
			if (j >= weight[i])
				ExcelFunction[i][j] = max( ExcelFunction[i - 1][j - weight[i]] + value[i], ExcelFunction[i - 1][j] );
			else
				ExcelFunction[i][j] = ExcelFunction[i - 1][j];
		}
	return ExcelFunction[num][totalweight];
}
int main()
{
	int value[Maxsize] = { 0 }, weight[Maxsize] = { 0 };//价值,重量
	cout << "请输入包裹总数和总重量:" << endl;
	cin >> num >> totalweight;
	cout << "请输入包裹价值和重量:" << endl;
	for (int i = 1; i <= num; i++)//价值,重量
		cin >> value[i] >> weight[i];
	cout << "可容纳最大价值为:" << DP(value, weight) << endl;
	system("pause");
	return 0;
}

运行结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44116998/article/details/102231861
今日推荐