01背包动态规划法

01背包动态规划法

思路

二维数组记录每次的选择,i行为物品,j列为体积
当选择1号物品时,体积从1-max;
再选择2号,以此类推。
如果选择当前物品的体积大于背包剩余容量,则选择之前的物品dp[i][j] = dp[i - 1][j];
如果选择当前物品的体积小于背包剩余容量,则在选择当前物品和不选择当前物品两个结果中,选择一个价值最大值dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
dp[i - 1][j - w[i]] + v[i]为选择了当前物品,选择当前物品为选择上一个物品+当前物品。

代码实现

#include<iostream>
using namespace std;

int w[333] = { 0 };			//商品的体积
int v[333] = { 0 };			//商品的价值
int m,n;				        //m背包大小,n商品数量
int dp[222][222] = { { 0 } };			        //动态规划表
int item[2222];  //选择了哪个商品
void findMax() {					//动态规划
	for (int i = 1; i <=n; i++) {
		for (int j = 1; j <= m; j++) {
			if (j < w[i])
				dp[i][j] = dp[i - 1][j];
			else
				dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
		}
	}
}


void findWhat(int i, int j) {				//最优解情况
	if (i >= 0) {
		if (dp[i][j] == dp[i - 1][j]) {
			item[i] = 0;
			findWhat(i - 1, j);
		}
		else if (j - w[i] >= 0 && dp[i][j] == dp[i - 1][j - w[i]] + v[i]) {
			item[i] = 1;
			findWhat(i - 1, j - w[i]);
		}
	}
}

void print() {
	int x = 0;
	for (int i = 1; i <= n; i++) {			//动态规划表输出
		for (int j = 1; j <= m; j++) {
			if (dp[i][j] > x)
				x = dp[i][j];
		}
		
	}
	cout << "最大价值为:";
	cout << x;
	cout << endl;
	cout << "选择的物品为:";
	for (int i = 1; i <= n; i++)
	{
		if (item[i] == 1)
			cout << i << " ";
	}
	cout << endl;
	
}
void init() {
	int i;
	cin >> m >> n;
	for (i = 1; i <= n; i++) {
		cin >> w[i] >> v[i];
	}
}
int main()
{
	init();
	findMax();
	findWhat(n, m);
	print();

	return 0;
}
posted @ 2024-06-30 15:49  高浩杰  阅读(19)  评论(0)    收藏  举报