回溯思想解排列问题(一)

<pre name="code" class="cpp">

搜索基本上算是算法的入门槛了,后续很多问题都是基于回溯思想的搜索性质解题的,当然这里暂且指的是深搜(这是一个递归函数,调试起来很不方便)。所以在忍了两个月之后要在这里总结一下深度搜索问题,毕竟要想在二十分钟之内解决好一道深搜题还是不容易的,关键的是,这种递归的思想熟练以后对于很多算法的递归表达就十分熟练敏感了。什么迭代加深,tarjan算法,树的直径等等……

这里先说回溯法的理由,虽然经典的是八皇后问题,但是深搜仿佛更容易理解:

1.只考虑当前状态和下一步的操作,以前的事已经办过了,不需要考虑。

2.尝试成功之后消除影响,因为可能性不是一种,为下次提供方便,否则一条路到头就死了,这就是回溯。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>

using namespace std;
const int maxn=1010;
int data[maxn];
bool vis[maxn];
int n;

void permulate(int d)           //表示到达d层,现在填的是data[d],具体填什么,不知道,看具体的i
{
    if(d==n)                    //如果深度到达d,那么表示此次尝试成功,输出,返回
    {
        for(int i=0;i<n;i++)
            cout<<data[i]<<" ";
        cout<<endl;
    }
    for(int i=1;i<=n;i++)       //这是data的数据源,已经填入的标1,没有填的标0,当然填入的是标0的
    {
        if(!vis[i])             //找到了,都填入d层
        {
            data[d]=i;          //填入
            vis[i]=1;           //标记已经填过
            permulate(d+1);     //进行下一次操作,当程序从这个函数跳出来的时候,表示d-n已经填好了
            vis[i]=0;           //为什么要再次标0呢?因为他已经在permuate(d+1)用过了,现在出来了,要消除影响
        }
    }
}

int main()
{
    while(cin>>n)
    {
        memset(vis,0,sizeof(vis));
        permulate(0);                   //从零下标开始填入
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章