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
*/