01背包------回溯法(包括回溯法讲解)

回溯法讲解:

对于这个回溯的概念,百度一下都会有很多的概念说法,但是都会很绕,讲的似懂非懂,看书更是,我就说一下个人的理解吧。
1.回溯法主要就是基于深度优先搜索的思想,这样说是因为还有一个叫做分支限界法的东东,他是基于广度优先搜索的思想,这俩比较像。
2.回溯法实施的主要框架就是在一棵树上,有的是子集树,有的是排列树,针对这棵树进行搜索。
3.回溯法不是单纯的去建立这棵树,而是利用这样一颗不存在的树去进行,搜索,所以一些同学不要进入到一种去建立一颗真实的二叉树或者树的思想里去。
4.回溯法是对于一个问题再进行到一个部分的时候,深度搜索直到结束,返回到原先的部分的时候需要将原先的部分恢复,类似于中断的断点。
5.实现的方法一般递归比较容易实现,可以使用迭代的方法,就是非递归,我的理解。

我的理解差不多就是这样,大家有觉得错的可以留言。

01背包问题;

问题描述:
这个我就不想写了,自己去搜,很多,真的。
这个问题有很多方法可以去实现,这里讲解的是回溯法的实现方法。
题目比较简单我就直接上代码,里面有注释:

#include <stdio.h>
#include <stdlib.h>
#define maxx 3
//递归实现回溯
//回溯就是递归的结束,返回上一层需要进行数据的返回类似于中断的断点保护
//子集树
//回溯法只要就是要有约束函数和限界函数(左,右);
//限界函数:当前所有的价值+剩余的所有价值之和小于bestv,则减去右子树;
int c=30;
int cw=0;
int cv=0;
int w[maxx]={20,15,15};
int v[maxx]={40,25,25};
int bestv=0;
int n=3;
int flag=0;
int X[maxx];
void getBest(int i);
int Prize(int i);
int main()
{
    getBest(0);
    printf("最优的结果是%d\n",bestv);

    return 0;
}

void getBest(int i){
    int z;
    int j;
   if(i>=n){//递归结束的判断结束条件,在当前最后一个可执行条件的下一个
        if(cv>bestv)
        bestv=cv;
        flag=1;
    return ;
   }
   if(cw+w[i]<=c){//进入左子树//约束函数
       X[i]=1;
       cw+=w[i];
       cv+=v[i];
       getBest(i+1);
       cw-=w[i];//回溯的过程
       cv-=v[i];
   }
   if(flag==1){//减支函数,减去(i+1~n-1的价值+cw)<bestv的部分
    z=Prize(i);
    if(z<bestv-cv)
    {
        for(j=0;j<=i-1;j++)//判断的是i不装,然后需不需要继续讨论i不装的问题
            printf("%d",X[j]);
        printf("\n");
    return ;
    }
   }
   X[i]=0;//1.不经过左子树直接到右子树,2.计算过左子树,然后回溯到右子树
   getBest(i+1);
}
int Prize(int i){
   int j;
   int z=0;
   for(j=i+1;j<n;j++)
    z+=v[j];
   return z;
}

欢迎给出意见。

    原文作者:回溯法
    原文地址: https://blog.csdn.net/m0_37789800/article/details/78414534
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞