|
|
|
@ -0,0 +1,77 @@
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
using namespace std;
|
|
|
|
|
typedef struct{
|
|
|
|
|
int v;
|
|
|
|
|
int w;
|
|
|
|
|
int no;
|
|
|
|
|
}goods;
|
|
|
|
|
int n,c;//物品数量,背包容量
|
|
|
|
|
int *x;//当前解
|
|
|
|
|
goods *a;//物品
|
|
|
|
|
int bv,*bx;//最优值,最优解
|
|
|
|
|
int cc,cw;//当前价值,当前重量
|
|
|
|
|
|
|
|
|
|
int cmp(goods a,goods b)//约定sort 所用cmp函数
|
|
|
|
|
{
|
|
|
|
|
return a.v*b.w>=a.w*b.v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float Bound(int step){//贪心算法求得当前状态下对应背包的最优值
|
|
|
|
|
int i,m=c-cw;
|
|
|
|
|
float b=cc;
|
|
|
|
|
for(i=step; i<=n&&a[i].w<=m;i++)
|
|
|
|
|
b+=a[i].v, m-=a[i].w;
|
|
|
|
|
if(i<=n)
|
|
|
|
|
b+=(m*1.0/a[i].w)*a[i].v;
|
|
|
|
|
return b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void dfs(int step){
|
|
|
|
|
int i;
|
|
|
|
|
if(step>n){//叶子结点
|
|
|
|
|
if(cc>bv){
|
|
|
|
|
bv=cc;
|
|
|
|
|
for(i=1;i<=n;i++)bx[a[i].no]=x[i];//序号还原
|
|
|
|
|
}
|
|
|
|
|
return;//回头
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(cw+a[step].w<=c){//满足约束条件,进入左子树
|
|
|
|
|
x[step]=1;
|
|
|
|
|
cc+=a[step].v;cw+=a[step].w;
|
|
|
|
|
dfs(step+1);
|
|
|
|
|
cc-=a[step].v;cw-=a[step].w;//恢复现场
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(Bound(step+1)>bv){//满足上界条件,进入右子树
|
|
|
|
|
x[step]=0;
|
|
|
|
|
dfs(step+1);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(){
|
|
|
|
|
int i;
|
|
|
|
|
cout<<"请输入物品个数n:"<<endl;
|
|
|
|
|
cin>>n;
|
|
|
|
|
a=new goods[n+1];
|
|
|
|
|
bx=new int[n+1];
|
|
|
|
|
x=new int[n+1];
|
|
|
|
|
cc=0;
|
|
|
|
|
cw=0;
|
|
|
|
|
bv=0;
|
|
|
|
|
cout<<"请输入背包容量c:"<<endl;
|
|
|
|
|
cin>>c;
|
|
|
|
|
for(i=1;i<=n;i++)a[i].no=i,x[i]=0;
|
|
|
|
|
printf("请依次输入%d个物品的价值:\n",n);
|
|
|
|
|
for(i=1;i<=n;i++)cin>>a[i].v;
|
|
|
|
|
printf("请依次输入%d个物品的重量:\n",n);
|
|
|
|
|
for(i=1;i<=n;i++)cin>>a[i].w;
|
|
|
|
|
dfs(1);
|
|
|
|
|
printf("最优价值为:%d\n",bv);
|
|
|
|
|
cout<<"最优解为:"<<endl;
|
|
|
|
|
for(i=1;i<=n;i++)cout<<bx[i]<<'\t';
|
|
|
|
|
cout<<endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|