转自:http://blog.csdn.net/jianfpeng241241/article/details/51893105?locationNum=2&fps=1
#include <iostream>
using namespace std;
const int N = 4;//物品个数
const int V = 17;//背包最大容量
int weight[N + 1] = {0,7,7,5,4};//物品重量
//int value[N + 1] = {0,5,10,20};//物品价值
int f[N + 1][V + 1] = {{0}};
int Max(int x,int y)
{
return x > y ? x : y;
}
/*
目标:在不超过背包容量的情况下,最多能获得多少价值
子问题状态:f[i][j]:表示前i件物品放入容量为j的背包得到的最大价值
状态转移方程:f[i][j] = max{f[i - 1][j],f[i - 1][j - weight[i]] + value[i]}
初始化:f数组全设置为0
*/
int Knapsack()
{
//初始化
//递推
for (int i = 1;i <= N;i++) //枚举物品
{
for (int j = 1;j <= V;j++) //枚举背包容量
{
f[i][j] = f[i - 1][j];
if (j >= weight[i])
{
f[i][j] = Max(f[i - 1][j],f[i - 1][j - weight[i]] + weight[i]);
}
}
}
return f[N][V];
}
/*
输出顺序:逆序输出物品编号
注意:这里借助状态数组f[i][v]
使用状态转移方程:f[i][j] = max{f[i - 1][j],f[i - 1][j - weight[i]] + value[i]}
*/
void PrintKnapsack()
{
int i = N;//枚举物品
int j = V;//枚举空间
cout<<"加入背包的物品编号:"<<endl;
while(i)
{
if (f[i][j] == f[i - 1][j - weight[i]] + weight[i])
{
/*if不满足,表示第i件物品没装入背包,
if条件满足,表示放入背包了*/
cout<<i<<" ";
j -= weight[i];//此时容量减少
}
i--;
}
cout<<endl;
}
/*
输出顺序:顺序输出物品编号
注意:这里借助状态数组f[i][v]
使用状态转移方程:f[i][j] = max{f[i - 1][j],f[i - 1][j - weight[i]] + value[i]}
*/
void PrintKnapsack_recursion(int i,int j)
{
if (i == 0 || j == 0)
{
return;
}
if (f[i][j] == f[i - 1][j - weight[i]] + weight[i])
{
PrintKnapsack_recursion(i - 1,j - weight[i]);
cout<<i<<" ";
}
}
int main()
{
cout<<Knapsack()<<endl;
PrintKnapsack();
PrintKnapsack_recursion(N,V);
system("pause");
return 1;
}
压缩空间:
#include <iostream>
using namespace std;
const int N = 3;//物品个数
const int V = 5;//背包最大容量
int weight[N + 1] = {0,3,2,2};//物品重量
int value[N + 1] = {0,5,10,20};//物品价值
int f[V + 1] = {0};
int G[N + 1][V + 1] = {{0}};//求背包序列
int Max(int x,int y)
{
return x > y ? x : y;
}
/*
目标:在不超过背包容量的情况下,最多能获得多少价值
子问题状态:f[j]:表示前i件物品放入容量为j的背包得到的最大价值
状态转移方程:f[j] = max{f[j],f[j - weight[i]] + value[i]}
初始化:f数组全设置为0
*/
int Knapsack()
{
//初始化
memset(f,0,sizeof(f));
memset(G,0,sizeof(G));
//递推
for (int i = 1;i <= N;i++) //枚举物品
{
for (int j = V;j >= weight[i];j--) //枚举背包容量
{
if (f[j] < f[j - weight[i]] + value[i])
{
f[j] = f[j - weight[i]] + value[i];
G[i][j] = 1;
}
}
}
return f[V];
}
/*
输出顺序:逆序输出物品编号
注意:这里另外开辟数组G[i][v],标记上一个状态的位置
G[i][v] = 1:表示物品i放入背包了,上一状态为G[i - 1][v - weight[i]]
G[i][v] = 0:表示物品i没有放入背包,上一状态为G[i - 1][v]
*/
void PrintKnapsack()
{
int i = N;//枚举物品
int j = V;//枚举空间
cout<<"加入背包的物品编号:"<<endl;
while(i)
{
if (G[i][j] == 1)
{
/*if不满足,表示第i件物品没装入背包,
if条件满足,表示放入背包了*/
cout<<i<<" ";
j -= weight[i];//此时容量减少
}
i--;
}
cout<<endl;
}
/*
输出顺序:顺序输出物品编号
注意:这里另外开辟数组G[i][v],标记上一个状态的位置
G[i][v] = 1:表示物品i放入背包了,上一状态为G[i - 1][v - weight[i]]
G[i][v] = 0:表示物品i没有放入背包,上一状态为G[i - 1][v]
*/
void PrintKnapsack_recursion(int i,int j)
{
if (i == 0 || j == 0)
{
return;
}
if (G[i][j] == 1)
{
PrintKnapsack_recursion(i - 1,j - weight[i]);
cout<<i<<" ";
}
}
int main()
{
cout<<Knapsack()<<endl;
PrintKnapsack();
PrintKnapsack_recursion(N,V);
system("pause");
return 1;
}