回溯思想解排列問題(一)

<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;
}


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