搜索思路總結

搜索個人感覺最重要的就是確定對狀態的定義,之後的動規最重要的也是狀態的確定。

狀態確定的好那麼搜索也就相對容易,而對於狀態的確定需要通過一些題目來進行總結。

例題1.

立體八數碼問題

八數碼是對空格的搜索,那麼很明顯空格的位置是一個描述狀態的量,id表示空格的編號,此外步數也是一個描述狀態的量,這個時候思考有了這兩個參量是否能唯一確定狀態呢,空格一樣,步數一樣,但其他的各自狀態可能不一樣,所以其他的8個方塊的狀態也應該記錄,此時再來檢查狀態是否唯一呢,9個方塊狀態一模一樣並且步數相同。完全可以唯一確定狀態,那麼此時狀態就已經確定好了。此題由於狀態空間很大,那麼採用雙向bfs,此時按層數搜索,用優先隊列存儲狀態,編號需要花一些功夫,此題強烈建議寫一寫。

struct Node
{
    int t,n,s;
    Node(int _t,int _n,int _s):t(_t),n(_n),s(_s){}
    bool operator < (const Node &a) const {
        return t>a.t;
    }
};

以上是定義狀態的部分。

例題2.

UVA11214 守衛鍵盤

也是同樣的問題,其實這道題相對簡單,跟八皇后問題比較相似,皇后的個數以及當前走到哪個位置,當然這道題是要使用迭代加深的,所以加上搜索層數的限制就構成了搜索需要的參數

 

int dfs(int d, int cur, int maxd) {
    if(d == maxd) {
        if(arrvied()){
            printf("Case %d: %d\n", ++kase, d);
            return 1;
        }
        return 0;
    }
    else {
        for(int pos = cur; pos < n*m; pos ++) {
            int r = pos/m, c = pos%m;
            int tmp_a = vis[0][r], tmp_b = vis[1][c], tmp_c = vis[2][r+c], tmp_d = vis[3][c-r+n];
            vis[0][r] = vis[1][c] = vis[2][r+c] = vis[3][c-r+n] = 1;
            if(dfs(d+1, pos, maxd)) return 1;
            vis[0][r] = tmp_a; vis[1][c] = tmp_b; vis[2][r+c] = tmp_c; vis[3][c-r+n] = tmp_d;
        }
    }
    return 0;
}

以上搜索代碼也比較簡單,貼出代碼只是爲了看看搜索的參數。

搜索之前確定好狀態量,事半功倍。

 

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