回溯法: 01背包问题,用回溯法需要构造解的子集树以寻找最优解。只要左子节点是可一个可行结点,搜索就进入其左子树。对于右子树时,先计算上界函数,以判断是否将其减去。
上界函数: 当前价值 + 剩余容量可容纳的最大价值。
//回溯函数
void backtrack(int i)
{
if(i>n)//结束条件
{
bestp = cp;
return;
}
if(cw+w[i]<=c)//能放就放进去(左子树)
{
cw+=w[i];
cp+=v[i];
backtrack(i+1);//递归
cw-=w[i];//恢复到不放入状态
cp-=v[i];
}
if(bound(i+1)>bestp)//右子树
backtrack(i+1);
}
//上界函数
double bound(int i)
{
double lw= c-cw;
double bd = cp;
while(i<=n && w[i]<=lw)
{
lw-=w[i];
bd+=v[i];
i++;
}
if(i<=n)
bd+=v[i]/w[i]*lw;
return bd;
}