0-1背包问题 算法概论 c++/c 实现

题目:

给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为W(假定物品重量与背包容量值均为整数)
,应如何选择装入背包中的物品,使得装入背包中物品的总价值最大?设计一个动态规划算法,求解背包问题。

算法思想:

利用动态规划实现
1、定义子问题:
首先考虑参数的确定,在背包问题中,有关参数有 第i件物品以及加入物品后剩余的weight,在这里我们定义从1到i的取部分物品的最优解为B(i,w)。
2、确认DP方程:
这里就有两种情况
case 1:到第i-1件物品时,背包已经满了,显然价值已经最大,那么此时B(i,w)=B(i-1,w);
case 2:当背包未满的时候,最优解就是加入第i件物品或不加入第i件物品较优的那个,即max{B(i-1,w),vi+B(i,w-wi)}
那么base case就是没有物品时的总价值,即B(0,0)=0;
综合起来得到:
在这里插入图片描述3、子问题的求解次序:
这里我们假设每一件物品的重量都是整数,那么根据动态规划的基本方法,我们建立一个矩阵来求解这个DP方程。在这里插入图片描述自上而下,自左向右经过DP方程的计算将数据填入表格,那么最后一行最后一列就是整个背包的最优价值。

我们先给出伪代码,具体代码实现见下方
在这里插入图片描述
我们来看一下这个算法的时间复杂度:
在这里插入图片描述
这里可以看出来,这个算法的时间复杂度不仅与n(物品个数)有关,还与背包的最大载重有关,而蛮力法的时间复杂度显然是物品序列的自己个数即O(2^n),假如W >2^n时,动态规划反而低效。

代码来啦:

/*给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为W(假定物品重量与背包容量值均为整数)
,应如何选择装入背包中的物品,使得装入背包中物品的总价值最大?设计一个动态规划算法,求解背包问题。*/
#include <iostream>
#include <vector>
using namespace std;
void knapsack(int products_count, int capacity, vector<int>&weight, vector<int>&value,vector<vector<int>>&result)
{
	for (int i = 1; i <= products_count; i++)
	{
		for (int w = 1; w <= capacity; w++)
		{
			if (weight[i] <= w)
			{
				if (value[i] + result[i - 1][w - weight[i]] > result[i - 1][w])
				
					result[i][w] = value[i] + result[i - 1][w - weight[i]];
				
				else
					result[i][w] = result[i - 1][w];
			}
			else
				result[i][w] = result[i - 1][w];
		}
	}
}
void Print(vector<vector<int>>&result, vector<int>weight, vector<int>&x, int products_count, int capacity)
{
	for (int i = products_count; i >= 2; i--)
	{
		if (result[i][capacity] == result[i - 1][capacity])
			x[i] = 0;
		else
		{
			x[i] = 1;
			capacity = capacity - weight[i];
		}
	}
	x[1] = result[1][capacity] ? 1 : 0;
}
int main()
{
	int products_count, capacity;
	vector<int>weight(1, 0);
	vector<int>value(1, 0);
	//输入商品个数和背包容量
	cin >> products_count >> capacity;
	//输入商品重量与价格
	for (int i = 1; i <= products_count; i++)
	{
		int temp;
		cin >> temp;
		weight.push_back(temp);
	}
	for (int i = 1; i <= products_count; i++)
	{
		int temp;
		cin >> temp;
		value.push_back(temp);
	}
	vector<vector<int>>result(products_count + 1, vector<int>(capacity + 1, 0));//初始化结果矩阵
	knapsack(products_count, capacity, weight, value, result);
	vector<int>x(6, 0);
	Print(result, weight, x, products_count, capacity);
	for (int i = 1; i <= products_count; i++)
		cout << x[i] << " ";
	cout << endl;
	cout << result[products_count][capacity] << endl;
	system("pause");
	return 0;
}

运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/NiZjiTouA/article/details/89374918