01背包问题回溯法
#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()//按比值進(jìn)行排序
{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])//根據(jù)比率進(jìn)行排序,盡量拿比值最大的物品 {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說(shuō)明物品全都能被放入 {MAX_put = cv;return;}if(cw+w[i]<=c)//未到達(dá)極限容量 {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<<"請(qǐng)輸入物品數(shù)量及背包容量:";cin>>n>>c; for(i=1;i<=n;i++){cout<<"請(qǐng)輸入第"<<i<<"件物品重量和價(jià)值:";cin>>w[i]>>v[i];order[i]=i;}knapsack();backtrack(1);cout<<"最大價(jià)值為:"<<MAX_put;cout<<"放入背包的物品編號(hào)為:";for(i=1;i<=n;i++){if(put[i]==1)cout<<order[i]<<" ";}return 0;
}
總結(jié)
- 上一篇: 使用贪心算法解决最小生成树问题。
- 下一篇: 科学数据中心资源和用户访问控制体系