分析:
题目要求求得的是背包容量为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;
}