迭代加深搜尋

2021-10-02 08:51:42 字數 1666 閱讀 2494

深度優先搜尋每次選定乙個分支,然後往下搜尋,直到遞迴邊界

才回溯。這種策略有一點缺陷,那就是當搜尋樹的分支數目特別

多,並且答案在某個較淺的節點上,如果dfs在一開始就選錯了分

支,那就會在沒有答案的深層次浪費時間

當搜尋樹規模隨著層次的深入增長很快,並且能

夠確保答案在乙個較淺的節點上時,就可以使用

迭代加深搜尋的深度優先搜尋來解決問題

原題來自:zoj 1937

已知乙個數列a0,a1...am(其中 a0 = 1 , am = n , a0現給定 n 的值,要求 m的最小值(並不要求輸出),及這個數列每一項的值(可能存在多個數列,只輸出任乙個滿足條件的就可以了) 

多組資料,每行給定乙個正整數 n 。 

輸入以 0 結束。 

對於每組資料,輸出滿足條件的長度最小的數列。

5712

1577

0

1 2 4 5

1 2 4 6 7

1 2 4 8 12

1 2 4 5 10 15

1 2 4 8 9 17 34 68 77

提示

資料範圍與提示

1≤n≤100,1≤k≤m

搜尋框架:先搜尋列舉乙個k,列舉i和j作為分支,把a[i]和a[j]的和填到

a[k]上,然後遞迴寫下乙個位置

加入以下剪枝:

1.優化搜尋順序,為了讓序列中的數盡快逼近n,i和j從大到小列舉

2.排除等效操作,對於不同的i或j,a[i]和a[j]可能是相等的,可以在列舉時用乙個vis陣列對a[i]+a[j]進行判重,避免重複搜尋某乙個和

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define maxn 105 

using namespace std;

typedef long long ll;

const int n = 1e5+10;

const int m = 1e5+10;

const int mod = 1e9+7;

const double pi = acos(-1.0);

const double exp = 1e-8;

const int inf = 0x3f3f3f3f;

int n;

int a[1005];

int vis[maxn];

int cnt;

bool dfs(int dep)

for(int i = dep-1 ; i >= 1 ; --i)

for(int j = i ; j >= 1 ; --j)

}}int main()

for(int i = 1 ; i <= cnt ; ++i)

cout << a[i] << " ";

cout << endl;

} }return 0;

}

迭代加深搜搜尋

對於可以用回溯法求解但解答樹的深度沒有明顯上限的題目,可以考慮使用迭代加深搜尋。經典問題 埃及分數問題 給出乙個分數,比如19 45,把它寫成若干個形如1 ri的分數的和的形式,比如19 45 1 5 1 6 1 18,要求分母不能重複使用並且使用的分數的個數最少。如果有多組個數相同的解,最後的分數...

IDDFS迭代加深搜尋

includeusing namespace std const int maxn 10 int n,a maxn bool ans sort return true int h bool dfs int d,int maxd return false int solve return max an...

IDA 搜尋 迭代加深

首先放一道例題 給出n個數,以及目標m,需要用這n個數中的若干個數加起來等於m,問所有方案中使用的數的數量最少的方案是什麼。顯然,對於這道題,我們並不知道搜尋的深度會是多少,如果放任程式像野狗一樣滿場子亂搜,那麼肯定tle無疑了。由於需要記錄答案,所以用廣搜的話空間可能會炸。於是,我們只能用深搜,為...