用回溯法做0-1背包问题,这两行(程序中标注)是干嘛?为啥又要减?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用回溯法做0-1背包问题,这两行(程序中标注)是干嘛?为啥又要减?相关的知识,希望对你有一定的参考价值。

//回溯函数
void backtrack(int i)

double bound(int j); //声明后面要用到的限界函数
//到达叶子结点
if(i>n)

bestp=cp;
return;

//搜索左子树
if(cw+w[i]<=c)

cw+=w[i];
cp+=p[i];
put[i]=1;
backtrack(i+1);
cw-=w[i];??????????????什么意思》????
cp-=p[i];??????????????什么意思??????

//符合条件才搜索右子树
if(bound(i+1)>bestp)
backtrack(i+1);

看来新手对于回溯还是比较难以理解的,其实很简单啊 ,就是一个递归啊,递归啊楼主就是自己调用自己啊,自己调用自己啊,你初中就学过了啊。

比如 f[i] = f[i-1] + 3; 好了现在我跟你说f[0] = 1 , 那么f[10]怎么求呢,就是不断的迭代那个公式啊,写成代码就是

int f(int i)

    if(i == 0) return 1;
    return f[i-1] + 3;

i = 0 是整个递归的边界,就是到i = 0 的时候不继续迭代了,直接返回了,然后一层一层返回。

比如求f(2) = f(1) + 3 = (f(0)+3) +3 ,其中f[0] = 1,好了不断往左迭代就能算出f(2)了。好了我知道楼主要说我废话了,想说你问的又不是这个是吧,但是真的无关了?

我们再来看看你给的代码吧

void backtrack(int i)

    double bound(int j); //声明后面要用到的限界函数
    //到达叶子结点
    if(i>n)//这个就是边界,因为这边他没有调用自己而是直接返回了,
    对应了我们上面的i = 0;递归一定要有边界!
    
       bestp=cp;
       return;
    
    //当不是边界的时候呢,既然是递归那肯定就是自己调自己了
    if(cw+w[i]<=c)
    
        cw+=w[i];
        cp+=p[i];
        put[i]=1;
        backtrack(i+1);//这边就在自己调用自己了,下边那个backtrack(i+1)也一样
        
        cw-=w[i];//好了楼主的问题来了,这边在干吗?好了要知道这边在干吗,必须要知道这条语句什么时候执行啊!那么这条语句什么时候执行呢?当然是上面那条语句执行完毕之后执行啊,楼主也看到了上面是个递归函数,对应到我们上面的递推公式,他要一直自己调用自己啊,直到边界。那么在这个函数里,边界就是上面的i>n,那么究竟是什么意思呢?也就是说这执行这条语句之前,我都已经搜索到叶子节点了,而且已经返回了,就是说当取了第i这个物品的时候呢,后面所有的情况我都已经处理完了。那么我是不是该处理当不取第i这个物品了呢,那么我就要把刚刚取了第i个物品的重量和价值减掉,因为我现在要处理的是不取他们,所以这边把刚刚加的给减掉还了,这就是所谓的回溯,楼主好好体会一下,其实没有那么复杂的,你想啊backtrack(int i)这个函数是在干吗,不就是计算以i为父节点的子树能取到的最大价值么,那么backtrack(i+1)就是计算以i+1为父节点的子树能取到的最大值啊。那么我取了i节点去计算一下backtrack(i+1),然后我在不取i节点去计算一下backtrack(i+1),整个程序大概就是这个思想,你的问题就是在不取i节点的时候把当时取i节点的加上去的值减掉还原成不取i节点时的情况,这也是回溯的中心思想。
其实你还可以这么分析:假设这边只有两层,也就是说只有2件物品,那么是不是很好跟踪程序呢,这叫降低规模。
        cp-=p[i];//
    
    //符合条件才搜索右子树
    if(bound(i+1)>bestp)
        backtrack(i+1);

参考技术A /回溯函数
void backtrack(int i)

double bound(int j); //声明后面要用到的限界函数
//到达叶子结点
if(i>n)

bestp=cp;
return;

//搜索左子树
if(cw+w[i]<=c)

cw+=w[i];
cp+=p[i];
put[i]=1;
backtrack(i+1);
cw-=w[i];??????????????什么意思》????
cp-=p[i];??????????????什么意思??????

//符合条件才搜索右子树
if(bound(i+1)>bestp)
backtrack(i+1);

0-1背包问题如下,画用回溯法求解时的搜索情况,急用啊

有0-1背包问题如下:
n=6,c=20,P=(11,8,15,18,12,6),W=(5,3,2,10,4,2)。
画出用回溯法求解时的搜索情况。

参考技术A SHUI谁算法好 给我画个搜索树啊 回溯法求解的 n=4 c=20 p=(12,8,10,6)w=(6,3,8,5)

以上是关于用回溯法做0-1背包问题,这两行(程序中标注)是干嘛?为啥又要减?的主要内容,如果未能解决你的问题,请参考以下文章

0-1背包问题如下,画用回溯法求解时的搜索情况,急用啊

0-1背包问题的回溯法代码

0-1背包问题(回溯法)

0-1背包问题(回溯法)

0-1背包问题(回溯法)

0-1背包问题(回溯法)