0-1背包之一

#include <iostream> 
#include
<iomanip>
using namespace std;
const int max_n=100,max_w=10000;
int m[max_n][max_w],v[max_n],w[max_n],x[max_n];
//m[i][j]是背包容量为j,可选择物品为i,i+1,…,n时的最优值,即装入背包物品的总价值最大 x[]记录选择哪个物品
int c,n,i,j;
void init()
{
cout
<<"请输入物品个数和背包容量:";
cin
>>n>>c;
cout
<<"input the value (v[i]):"<<endl;
for(i=1;i<=n;++i)
cin
>>v[i];
cout
<<"input the weight (w[i]):"<<endl;
for(i=1;i<=n;++i)
cin
>>w[i];
}
void knapsack()
{
memset(m,
0,sizeof(m));
for(i=w[n];i<=c;++i)
m[n][i]
=v[n];
for(i=n-1;i>1;--i)
{
for(j=0;j<=min(w[i]-1,c);++j)
m[i][j]
=m[i+1][j];
for(j=w[i];j<=c;++j)
m[i][j]
=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);
}
if(c<w[1])
m[
1][c]=m[2][c];
else
m[
1][c]=max(m[2][c],m[2][c-w[1]]+v[1]);

int cc=c;
for(i=1;i<n;++i)
{
if(m[i][cc]==m[i+1][cc])
x[i]
=0;
else
{
x[i]
=1; //x[i]=1表示选中物品i
cc-=w[i];
}
}
x[n]
=(m[n][cc])?1:0; //m[n][cc] 为 0 或 v[n]
}
void output()
{
cout
<<"最优值: "<<m[1][c]<<endl;
cout
<<"m数组的分布:"<<endl;
for(i=2;i<=n;++i)
{
for(j=0;j<=c;++j)
cout
<<setw(2)<<m[i][j]<<" ";
cout
<<endl;
}
cout
<<"得到的一组最优解如下:"<<endl;
for(i=1;i<=n;++i)
{
cout
<<x[i]<<" ";
}
cout
<<endl;
}
int main()
{
freopen(
"G:\\c++.txt", "r", stdin ) ;
init();
knapsack();
output();
return 0;
}


/*
sample:

5 10
6 3 5 4 6
2 2 6 5 4

*/

  

posted on 2011-08-22 11:42  sysu_mjc  阅读(138)  评论(0编辑  收藏  举报

导航