[テーマ別演習]パート1の検索

オリジナルリンク: http://www.cnblogs.com/BriMon/p/9768460.html

この記事内のリンク話題のリンクがアップ混合されたいくつかの説明の一部...

.DFS(深さ優先探索)

あまりにも少なすぎる水。

二.BFS(BFS)

同上。

のIII。メモリー

メモリの検索、私たちの状態は、再使用の意志不必要な時間のかかる二重カウント状態を防ぐために、我々は結果を記録することを述べることができるし、ライン上のクエリ結果テーブルです。

一般的にメモリの検索、およびDPは同等です。DPの再発は書き込まない場合は、メモリ検索の実装を検討することができますが、それは、わずかに大きいので、一定の再帰的であるため。メモリ検索は明らかな利点を持っていることは、我々が終了が、唯一の状態は、ライン上で終了します知っている状態を考慮することができないということです。

IV。剪定を検索

これは通常、問題の検索時間、高い複雑さを解決するために使用される深い知識、です。

原理的には貢献生成された答えを探して巨大な木の枝をカットすることは不可能です。

我々は唯一の剪定経験の効果を推定することができるので、検索+剪定時の複雑さは、$ O(形而上学)$です。

だから、とき、暴力と闘うための試験は、剪定、特に奇妙な形而上学の剪定を記述する必要があります。

いくつかの例:

1. Noip2015地主   。

貪欲カード、ストレートマルチブランドの他の可能な組み合わせを列挙し、完全な。

今$ ANS-1 $は剪定を終了する時ではない場合はプラス、剪定を最適化。

形状のみ2.Noip2009をターゲット

私は下半分以上は、あなたが検索の下半分から始めるならば、全体のボードは2つの部分、スペースの上半分に分割して、$のlowbitの$の最適化は一定過ごしました。この過去の水。

実際には、あなたはまた、グリッドによって検索することができ、優先順位はあまり満たされたグリッドを見つけることができます。

グリッドの残りの部分は、その後、剪定には、$ ANSの$より9小さい満たされている場合は$ A ^ * $の剪定は、あります。

剪定技術が一般的に使用されます

1.最適剪定。

2. $ A ^ *の$剪定。

3.検索の順序を変更し、最初の検索では、比較的少数で状態を拡大しました。

V.双方向全体の検索

全体の検索双方向その後、答えを満たしている場合、各検索の各層の開始と終了から検索を開始することです。

双方向全体の検索は大幅に時間の複雑さを改善し、半分よりも探索木より行うことができます。

 

幅双方向の検索は、通常2つの方法があります。

 

  1. 二つの方向が交互に延長します

  2. その方向に拡大する選択されたノードの数が少ないです。

 

方法2生成速度が大幅に効率を向上させる、不均衡の双方向ノード状態を克服します。

 

1.poj3523ハロウィーンの後の朝 

実際には、この問題はあまりにも$ $ BFSを指示することができますが、それでも双方向全体の検索時間と効率の追求に半減させることができます。

途中で六.meet

この違いと双方向の検索、バイナリ思考が問題である場合、層の数を半減検索し、マージします。

古典的な例は、NOI2001方程式を停止します

3溶液最初の検索の前に、結果は、ハッシュテーブルルックで格納され、そしてその後3つの溶液、ハッシュテーブルのクエリの数を発見されました。

あまりにも嫌なこの問題は、積極的にWAを法、ハッシュテーブルMLEで、MAPTと飛びます。

不治...

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <map>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
#define reg register
inline int read() {
    int res=0;char ch=getchar();bool fu=0;
    while(!isdigit(ch))fu|=(ch=='-'), ch=getchar();
    while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    return fu?-res:res;
}

int n, m;
int k[8], p[8];
int mi[155][155];
int ans;
map <int, int> mp;
void dfs1(int dep, int sum) 
{
    if (dep > n / 2) {
        mp[sum]++;
        return ;
    }
    for (reg int i = 1 ; i <= m ; i ++)
        dfs1(dep + 1, sum + k[dep] * mi[i][p[dep]]);
}

void dfs2(int dep, int sum) 
{
    if (dep > n) {
        ans += mp[-sum];
        return ;
    }
    for (reg int i = 1 ; i <= m ; i ++)    
        dfs2(dep + 1, sum + k[dep] * mi[i][p[dep]]);
}

int main()
{
    n = read(), m = read();
    for (reg int i = 1 ; i <= n ; i ++) k[i] = read(), p[i] = read();
    for (reg int i = 0 ; i <= m ; i ++)
    {
        mi[i][0] = 1;
        for (reg int j = 1 ; j <= m ; j ++) mi[i][j] = mi[i][j - 1] * i;
    }
    dfs1(1, 0);
    dfs2(n / 2 + 1, 0);
    cout << ans << endl;
    return 0;
}
方程的解数

七.迭代加深搜索(IDDFS)

某些题状态无限,bfs无法承受空间复杂度,可以限制dfs搜索的深度。

每次增加深度限制,每次可能对之前搜过的状态多次计算,但是由于状态每一层都扩展的十分多,所以相比于扩展一层,重复上面的状态的复杂度还是可以接受的。

1.codevs1288 埃及分数

可以逐步增加答案的分数的个数,然后可以限制住状态的无限扩展...其实我不会233(逃.

2.poj2248 Addition Chains   (此题解访问人数已经突破100人啦!!)

和上面一样逐步扩展答案的个数,然后再加上一些十分有用的剪枝,才能A掉这题,详情见链接。

八.迭代加深A*(IDA*)

普通迭代加深搜索加入A*剪枝。

 1.bzoj1085 骑士精神

估价函数的一小点变动可能导致时间上的很大的差别,详情点进链接看看。

2.poj2286The Rotation Game

估价函数为8-中间出现次数最多的数字的个数。

九.随机化

过于玄学,略过。

转载于:https://www.cnblogs.com/BriMon/p/9768460.html

おすすめ

転載: blog.csdn.net/weixin_30814329/article/details/94816915