#include<iostream>
#include<cstring>
using namespace std;
int n;
double c;
double v[100];
double w[100];
double cw = 0.0;
double cv = 0.0;
double MAX_put = 0.0;
double ratio[100];//比率
int order[100];
int put[100];
void knapsack()//按比值进行排序
{
int i,j;
int temporder = 0;
double temp = 0.0;
for(i=1;i<=n;i++)
ratio[i]=v[i]/w[i];
for(i=1;i<=n-1;i++)
{
for(j=i+1;j<=n;j++)
if(ratio[i]<ratio[j])//根据比率进行排序,尽量拿比值最大的物品
{
temp = ratio[i];
ratio[i]=ratio[i];
ratio[j]=temp;
temporder=order[i];
order[i]=order[j];
order[j]=temporder;
temp = v[i];
v[i]=v[j];
v[j]=temp;
temp=w[i];
w[i]=w[j];
w[j]=temp;
}
}
}
void backtrack(int i)
{
double bound(int i);
if(i>n)//i>n说明物品全都能被放入
{
MAX_put = cv;
return;
}
if(cw+w[i]<=c)//未到达极限容量
{
cw+=w[i];
cv+=v[i];
put[i]=1;
backtrack(i+1);
cw-=w[i];
cv-=v[i];
}
if(bound(i+1)>MAX_put)
{
put[i]=0;
backtrack(i+1);
}
}
double bound(int i)
{
double leftw= c-cw;
double b = cv;
while(i<=n&&w[i]<=leftw)
{
leftw-=w[i];
b+=v[i];
i++;
}
if(i<=n)
b+=v[i]/w[i]*leftw;
return b;
}
int main()
{
int i;
cout<<"请输入物品数量及背包容量:";
cin>>n>>c;
for(i=1;i<=n;i++)
{
cout<<"请输入第"<<i<<"件物品重量和价值:";
cin>>w[i]>>v[i];
order[i]=i;
}
knapsack();
backtrack(1);
cout<<"最大价值为:"<<MAX_put;
cout<<"放入背包的物品编号为:";
for(i=1;i<=n;i++)
{
if(put[i]==1)
cout<<order[i]<<" ";
}
return 0;
}
01背包问题回溯法
最新推荐文章于 2022-06-06 19:53:15 发布