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

回溯法理解,一般形式

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;
}
原文地址:https://www.cnblogs.com/xiumukediao/p/4705938.html