1. 程式人生 > >POJ2248——Addition Chains【DFS,迭代加深搜尋】

POJ2248——Addition Chains【DFS,迭代加深搜尋】

題目連線:http://poj.org/problem?id=2248

題目大意:現在有一個數組其中a[1] = 1,a[m] = n,並且a[1] < a[2] < ........< a[m],現在給你一個數n問,滿足條件的m的最小值為多少。其中1 <= n <= 9

大致思路:如果我們按照DFS直接搜尋的話,一共有n!個節點十分耗時,這個時候我們可以採用迭代加深搜尋,每一次搜尋限定好搜尋深度,並逐層增加搜尋深度,知道找到答案為止。

程式碼:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

const int MAXN = 110;
bool vis[MAXN];
int ans[MAXN];
int maxd,n;

bool DFS(int d){
	if(d > maxd){
        if(ans[maxd] == n) return true;
        else return false;
	}
	memset(vis,0,sizeof(vis));
	for(int i = d - 1; i >= 1; i--){
        for(int j = d - 1; j >= 1; j--){
            if(ans[i] + ans[j] <= ans[d - 1]) break;
            if(!vis[ans[i] + ans[j]] && ans[i] + ans[j] <= n){
            	ans[d] = ans[i] + ans[j];
            	vis[ans[d]] = 1;
            	if(DFS(d + 1)) return true;
            }
        }
	}
	return false;
}

int main(int argc, char const *argv[])
{
	while(~scanf("%d",&n) && n){
		bool ok = false;
		ans[1] = 1;
		//ans[0] = 0;
		if(n == 1) { cout << "1" << endl; continue; }
		for(maxd = 2; ; maxd++){
			memset(vis,0,sizeof(vis));
			if(DFS(2)) { ok = true; break; }
		}
		//cout << maxd << endl;
		if(ok){
			for(int i = 1; i < maxd; i++) cout << ans[i] << " ";
            cout << ans[maxd] << endl;
		}
	}
	return 0;
}