01背包问题

分析:

题目要求求得的是背包容量为c,有n个物品可选时的最大价值。很明显它有一个子结构,题目要求的结果可表示为dp[n][c],子问题dp[i][j]
表示背包容量为j,可选择物品为1~i时的最大价值。
状态转移公式为:
当j<w[i]时,dp[i][j]=dp[i-1][j]
当w[i]<=j<=c时,dp[i][j]=max(dp[i-1][j-w[i]]+v[i],dp[i-1][j])
const int c = 10;//总容量;
const int n = 5;//物品数;
vector<int> backpack(int v[], int w[]) {
	int dp[n + 1][c + 1];//dp[i][j]表示背包容量为j,可选择物品为1~i时的最大价值,代表一个子问题的解;
	vector<int> x(n, 0);//判断是否放第i个物品;
	for (int j = 0; j <= c; ++j)
		dp[0][j] = 0;
	for (int i = 0; i <= n; ++i)
		dp[i][0] = 0;
	for (int i = 1; i <=n; ++i) {//依次对物品进行遍历
		for (int j = 1; j < w[i] && j < c; ++j)//装不下第i个物品
			dp[i][j] = dp[i - 1][j];
		for (int j = w[i]; j <= c; ++j)//装得下第i个物品,但是装还是不装要看哪个的总价值更大
			dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
	}
	//求出x
	int spare = c;
	for (int i = n; i > 0; --i)
		//要从dp[n][c]开始计算
		if (dp[i][spare] == dp[i - 1][spare]) x[i - 1] = 0;
		else {
			x[i - 1] = 1;
			spare -= w[i];
		}
	return x;
}
原文地址:https://www.cnblogs.com/Frank-Hong/p/13329964.html