#include <iostream>
using namespace std;
// 参考 http://baike.baidu.com/link?url=kOn5J1ionfV40_l4SagPK3aO6vu6TAB4r9iPociRXEm6R0Er8JEb4wpE2_53GJe8vPQ-KLb8-Au6r3N4K8h6PDpxqMhyEkxWxZoFWcqlqfZhZJCjuFTVixTVbZx1Fzu7
void check(int n, int *w, int *v, int C, int **f){
// 放置第1个
for (int i = 0; i < C + 1; ++i){
if(w[0] <= i)
f[0][i] = v[0];
else
f[0][i] = 0;
}
// 放置后n-1个
for (int i = 1; i < n; ++i){
for (int j = 0; j < C + 1; ++j){
if(w[i] > j)
f[i][j] = f[i - 1][j];
else
// 不放置第i个物品 f[i][j] = f[i - 1][j]
// 放置第i个物品 f[i][j] = f[i - 1][j - w[i]] + v[i]
f[i][j] = f[i - 1][j] > (f[i - 1][j - w[i]] + v[i]) ? f[i - 1][j] : (f[i - 1][j - w[i]] + v[i]);
}
}
}
void solution(int n, int *v, int C, int **f, int *s){
// 第1个物品是否应该装入
if (f[0][C])
s[0] = 1;
// 后n-1个是否应该装入
for (int i = 1; i < n; ++i){
if(f[i][C] == f[i - 1][C])
s[i] = 0;
else
s[i] = 1;
}
}
int main()
{
int n = 5; // 物品总数
int w[]={2, 2, 6, 5, 4}; // 重量
int v[]={6, 3, 5, 4, 6}; // 价值
int C = 10; // 背包容量
// f[i][j]表示前i个物品装入容量j的背包时的最大价值
int **f = new int*[n];
for (int i = 0; i < n; ++i){
f[i] = new int[C + 1];
}
// s[i]表示最终第i个物品是否应该装入
int *s = new int[n];
check(n, w, v, C, f);
solution(n, v, C, f, s);
cout << "最优方案:\n";
for (int i = 0; i < n; ++i){
cout << s[i] << " ";
}
cout << "\n总价值:\n";
cout << f[n - 1][C] << endl;;
int ttt = 0;
return 0;
}