• 解决八皇后问题,递归与非递归方式两种


    回溯法理解,一般形式

    void Bcktrack(int t) //参数t表示当前递归深度
    {
        if(t>n)Output(x); //遍历到解,则将解输出或其他处理
        else
        {
            //f(n,t)和g(n,t)表示当前节点(扩展节点)处未搜索过的子树的起始编号和中指编号
            for(int i=f(n,t);i<=g(n,t);i++)    
            {
                x[t]=h(i);    //h(i)表示当前节点(扩展节点)处x[i]的第i个可选值
                if(Constarint(t)&&Bound(t)) //剪枝函数:约束函数,限界函数
                    Bcktrack(t+1);
            }
        }
    }

    例子一,八皇后问题

    // MyEightQueen.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    
    #include <VECTOR>
    #include <iostream>
    
    using namespace std;
    
    class EightQueen{
    public:
        EightQueen(int n){
            nqueen = n;
            solution.resize(nqueen + 1);
            numofsolutions = 0;
        }
        void put(){
            _put(1);
        }
        int getnumofsolutions(){
            return numofsolutions;
        }
    private:
    
        bool isplace(int n){
            for(int i=1 ; i<n ; i++){
                if(solution[i]==solution[n] || abs(n-i) == abs(solution[i] - solution[n]))
                    return false;
            }
            return true;
        }
        void _put(int n){
            if(n > nqueen){    //搜索到一个符合要求的解法
                for(int i = 1;i<=nqueen;i++)
                    cout<<solution[i]<<" ";
                cout<<endl;
                numofsolutions++;
            }
            else{
                for(int j = 1;j<=nqueen;j++){
                    solution[n] = j;
                    if(isplace(n))   //如果此处可以放置棋子,那么考虑放置下一个棋子,即_put(n+1)
                        _put(n+1);
                }
            }
        }
    private:
        vector<int> solution;
        int nqueen;
        int numofsolutions;
    };
    int main(int argc, char* argv[])
    {
        EightQueen example(8);
        example.put();
        cout<<"num of solutions "<<example.getnumofsolutions()<<endl;
        return 0;
    }

    例子二:01背包问题

    // 01Packet.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include "stdio.h"
    
    int m,n=5,x[10]={0};
    int w[6]={0,2,2,6,5,5},v[6]={0,6,3,5,4,6};
    int c=10;
    int cw=0,cv=0,bestv=0;
    
    int f(int k)
    {
        int i;
        if (k>n)             //已找到一个符合条件的解决方案
        {
            for(i=1;i<=n;i++)
                printf("%d",x[i]);
            printf("  cv = %d",cv);
            if(cv>bestv)
                bestv=cv;
            printf("
    ");
        }
        else
        {
            for(int i = 0;i <= 1;i++){
                x[k] = i;                 //H[i] = {0,1}
                int tempw = i*w[k] + cw;
                int tempv = i*v[k] + cv;
                
                if(tempw <= c){    //限制条件
                    cw = tempw;
                    cv = tempv;
                    f(k+1);        //进行下一层处理
                    cw -= i*w[k];  //回溯之后将子路增加的和删除
                    cv -= i*v[k];
                }
                
            }
            return k;
        }
    }
    
    int main(int argc,char * argv[]){
        f(1);
        printf("bestv is %d
    ",bestv);
        return 0;
    }
  • 相关阅读:
    神仙题1.0
    一些小技巧(持续更新。。)
    模板(持续更新中。。)
    「CTS2019 | CTSC2019」氪金手游(容斥+概率计数)
    Emacs配置
    AGC034E Complete Compres(dp)
    「清华集训 2017」榕树之心(换根dp)
    [NOI2018]冒泡排序 (卡特兰数)
    「清华集训 2017」小 Y 和二叉树 (贪心)
    「雅礼集训 2018 Day1」图 (dp套dp)
  • 原文地址:https://www.cnblogs.com/xiumukediao/p/4705938.html
Copyright © 2020-2023  润新知