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

*/

  

转载于:https://www.cnblogs.com/mjc467621163/archive/2011/08/22/2149116.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值