赞
踩
0-1背包
问题:给定n种物品和一背包。物品i的重量是wi,其价值为pi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
分析:问题是n个物品中选择部分物品,可知,问题的解空间是子集树。比如物品数目n=3时,其解空间树如下图,边为1代表选择该物品,边为0代表不选择该物品。使用x[i]表示物品i是否放入背包,x[i]=0表示不放,x[i]=1表示放入。回溯搜索过程,如果来到了叶子节点,表示一条搜索路径结束,如果该路径上存在更优的解,则保存下来。如果不是叶子节点,是中点的节点(如B),就遍历其子节点(D和E),如果子节点满足剪枝条件,就继续回溯搜索子节点。
#include<iostream>
using namespace std;
#define N 3
#define C 16
int weight[N]={10,8,5};
int value[N]={5,4,1};
int flag[N]={0,0,0};
int CurrentWight=0;
int CurrentValue=0;
int MaxValue=0;
int bestValue[N];
void backtrace(int x)
{
if(x>N-1)
{
if(CurrentValue>MaxValue){
MaxValue=CurrentValue;
for(int i=0;i<N;i++)
bestValue[i]=flag[i];
}
}
else
{
for(int i=0;i<=1;i++)
{
flag[x]=i;
if(i==0)
{
backtrace(x+1);
}
else
{
if(CurrentWight+weight[x]<=C)
{
CurrentWight+=weight[x];
CurrentValue+=value[x];
backtrace(x+1);
CurrentWight-=weight[x];
CurrentValue-=value[x];
}
}
}
}
}
int main()
{
backtrace(0);
cout<<"MaxValue:"<<MaxValue<<endl;
for(int i=0;i<N;i++)
{
cout<< bestValue[i]<<" ";
}
cout<<endl;
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。