POJ - 2248 Addition Chains(dfs+迭代加深)
生活随笔
收集整理的這篇文章主要介紹了
POJ - 2248 Addition Chains(dfs+迭代加深)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:我們規定加法鏈有如下特點:
現在給出一個數n,求該數的最短加法鏈
題目分析:這個題首先我們可以枚舉所有可能性,并且進行適當的剪枝:
當然經過分析大我們可以發現,這個題目的m最大在10左右
再經過分析我們可以得知,每次加和構成新的一個數,都必須有最后一個數字的參與,不然的話肯定不是最優解,這樣我們就能將每次dfs時n*n的復雜度下降到了n
這里我再掛一下迭代加深的定義和思想:(摘自zx學長的ppt)
深度優先搜索每次選定一個分支,不斷深入,直至到達遞歸邊界才回溯。這種策略帶有一定的缺陷。
搜索樹的每個節點的分支數目非常多,并且問題的答案在某個較淺的節點上。如果一開始就搜索錯了分支,就很可能在不包含答案的深層子樹上浪費很多時間。
我們可以從小到大限制搜索深度,如果在當前深度限制下搜不到答案,就把深度限制增加,重新進行一次搜索。
雖然該過程在深度限制為d時,會重復搜索第1--d-1層的節點,但是當搜索樹節點分支數目較多時,隨著層數的深入,每層節點會呈指數級增長,這點重復的搜索的節點與深層子樹的規模相比,實在是小巫見大巫了。
當搜索樹的規模隨著層次的深入增長很快,并且我們能夠確保答案在一個較淺的層次時,可以迭代加深。
?說到這里,我們就可以利用迭代加深的思想每層搜索這個題目的答案了
代碼:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=20;int n;int deep;//搜索樹的深度int a[N];bool dfs(int cnt) {if(cnt>deep)//當前深度搜索結束{if(a[deep]==n)//若找到答案,返回truereturn true;return false;}for(int i=cnt-1;i>=1;i--)//從大到小枚舉,可以保證不重不漏{a[cnt]=a[cnt-1]+a[i];if(a[cnt]>n)continue;if(dfs(cnt+1))return true;}return false; }int main() { // freopen("input.txt","r",stdin);a[1]=1;//直接設置好第一個數while(scanf("%d",&n)!=EOF&&n){if(n==1)//對1特判一下printf("1\n");else{deep=1;//初始化深度為第一層while(1){deep++;if(dfs(2))//每次從第二層開始搜索,搜到第deep層結束{printf("1");for(int i=2;i<=deep;i++)printf(" %d",a[i]);printf("\n");break;}} } }return 0; }?
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的POJ - 2248 Addition Chains(dfs+迭代加深)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ - 1190 生日蛋糕(dfs+
- 下一篇: HDU - 1043 Eight(bfs