目录
一、问题描述
思想
二、递归表达式1-从头装
1.递归方程式
2.代码
3.表格数据
编辑
三、递归表达式2-从尾装
1.递归方程式
2.代码
四、非递归代码
给定n种物品和一个背包,物品i的重量是w,价值是v,
如何选择放入的物品是装入背包的物品价值最大,不能只装入部分的该物品i
//m(i,j)即: m(i,j)背包重量j,可选择物品i,i+1,i+2....n
//i--物品个数,是区间值
例子:
五种物品
const int n = 5;
const int c = 10;
vector
vector
背包能容纳的质量j从0开始递增,放入第一个物品时,先初始化改行表中的数字,看物品wi是否可以放入背包,不可以填入0,可以放入vi,之后的每一行的填入,当前的wi>j时,不放入,并将之前放入的值填到当前位置即是(m(i-1,j)),可以放入时,比较放入的值和之前的值,大得填入表中
//非递归
int Knapsack(vector& w, vector& v, int n, int c, vector>& flag) {
if (n == 0) return 0;
for (int j = 1; j <= c; ++j) {
flag[1][j] = w[1] >= j ? 0 : v[1];
}
for (int i = 2; i <=n; ++i) {
for (int j = 1; j <= c; ++j) {
if (w[i] > j) {
flag[i][j] = flag[i - 1][j];
}
else {
flag[i][j] = max(flag[i - 1][j],flag[i-1][j-w[i]]+v[i]);
}
}
}
return flag[n][c];
}
//测试
int main()
{
const int n = 5;
const int c = 10;
vector w = { 0,2,2,6,5,4 };
vector v = { 0,6,3,5,4,6 };
vector> flag(n + 1, vector(c + 1,0));
int maxv = Knapsack(w, v, n, c, flag);
vector m(n + 1, false);
backx(flag, w, c, n, m);
for (int i = 1; i <= n; ++i)
{
if (m[i]) {
cout << i <<" ";
}
}
cout << endl;
cout << maxv << endl;
return 0;
}
int Knapsack(vector& w, vector& v, int n,int c,vector> &flag) {
if (n == 0) return 0;
for (int j = 0; j <=c; ++j) {
flag[n][j] = w[n] < j ? v[n] : 0;
}
for (int i = n - 1; i >= 1; --i) {
for (int j = 1; j <=c; ++j) {
if (j < w[i]) {
flag[i][j] = flag[i+1][j];
}
else {
flag[i][j] = max(flag[i + 1][j], flag[i + 1][j - w[i]]+ v[i]);
}
}
}
return flag[1][c];
}
int main()
{
const int n = 5;
const int c = 10;
vector w = { 0,2,2,6,5,4 };
vector v = { 0,6,3,5,4,6 };
vector> flag(n+1,vector(c+1,0));
int maxv = Knapsack(w, v, n,c,flag);
cout << maxv << endl;
return 0;
}
int Knapsack(vector& w, vector& v, int n, int c, vector>& flag) {
if (n == 0) return 0;
for (int j = 1; j <= c; ++j) {
flag[1][j] = w[1] >= j ? 0 : v[1];
}
for (int i = 2; i <=n; ++i) {
for (int j = 1; j <= c; ++j) {
if (w[i] > j) {
flag[i][j] = flag[i - 1][j];
}
else {
flag[i][j] = max(flag[i - 1][j],flag[i-1][j-w[i]]+v[i]);
}
}
}
return flag[n][c];
}