給定n種物品和一背包。物品i的重量是wi,其價值為vi,背包的容量為C。問應怎樣選擇裝入背包的物品,使得裝入背包中物品的總價值最大?
整個解的空間相當於一個二叉樹,左邊是0,代表不取這個物品,右邊是1,代表取這個物品,然后進行dfs,回溯的時候改動。
注意,這里應該有兩個剪枝,我這里僅僅寫了一個。
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int n,TotCap,bestval;//物品的個數。背包的容量,最大價值
const int N=1000;
int val[N],w[N],x[N],bestx[N];//物品的價值,物品的重量。x[i]暫存物品的選中情況,物品的選中情況
void dfs(int i,int cv,int cw)
{ //cw當前包內物品重量,cv當前包內物品價值
if(i>n)//結束
{
if(cv>bestval)
{
bestval=cv;
for(i=1;i<=n;i++)
bestx[i]=x[i];
}
}
else
for(int j=0;j<=1;j++)
{
x[i]=j;//取或者不取
if(cw+x[i]*w[i]<=TotCap)
{
cw+=w[i]*x[i];
cv+=val[i]*x[i];
dfs(i+1,cv,cw);
cw-=w[i]*x[i];
cv-=val[i]*x[i];
}
}
}
int main()
{
int i;
bestval=0;
cout<<"請輸入背包最大容量:"<<endl;;
cin>>TotCap;
cout<<"請輸入物品個數:"<<endl;
cin>>n;
cout<<"請依次輸入物品的重量:"<<endl;
for(i=1;i<=n;i++)
cin>>w[i];
cout<<"請依次輸入物品的價值:"<<endl;
for(i=1;i<=n;i++)
cin>>val[i];
dfs(1,0,0);
cout<<"最大價值為:"<<endl;
cout<<bestval<<endl;
cout<<"被選中的物品的標號依次是:"<<endl;
for(i=1;i<=n;i++)
if(bestx[i]==1)
cout<<i<<" ";
cout<<endl;
return 0;
}
