【poj2248】Addition Chains

Description

To play against the threats of malicious countries nearby, Country R has updated their missile defence system. The new type system can bring down a series of missiles as long as they are coming in ascending order by altitude or descending order by altitude.

Given the heights of a sequence of coming missiles, the general wants to know how many sets of the new type systems are needed to bring down all of them.

Input

The input consists of several test cases. The first line of each test case contains an integer n(1 ≤ n ≤ 50). The next line contains n different integers indicating the heights.

Output

For each test case output a single line containing the number of systems needed.

Sample Input

5
3 5 2 4 1
0 

Sample Output

2

HINT

Two sets of systems are needed for the sample. One brings down 3, 4 and the other brings down 5, 2, 1.

Source

POJ Founder Monthly Contest – 2008.10.05, facer
 
 
/*
    搜索思路:依次决定序列中每个位置填什么数,可枚举前面两个数的和作为新的数填充进序列。 
    剪枝:为了让搜索的数尽可能快地逼近n,枚举时倒序循环以加快速度。
    所求答案很小,可以使用迭代加深搜索,每次限制搜索深度,大于搜索深度就退出,第一次找到一组解就可以输出。
*/ 
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[1000000];
int n;
bool flag;
void dfs(int d,int depth){
    if (flag) return;
    if (d==depth){
        if (a[d]==n)    flag=true;
        return;
    }
    for (int i=d;i>=1;i--)
        for (int j=d;j>=i;j--)
            if (a[i]+a[j]<=n && a[i]+a[j]>a[d]){
                //剪枝,如果从当前一直往下都是选择最大的策略还是不能达到n,跳过 
                int jud=a[i]+a[j];
                for (int k=d+2;k<=depth;k++)
                    jud*=2;
                if (jud<n) continue;
                
                a[d+1]=a[i]+a[j];
                dfs(d+1,depth);
                if (flag) return;
            }
}
int main(){
    while(scanf("%d",&n) && n){
        flag=false;
        memset(a,0,sizeof(a));
        // 计算出至少需要多少步 
        int depth=0,m=1;
        while (m<=n){
            m*=2;
            depth++;
        }
        //从最少步开始进行迭代加深搜索  
        a[1]=1; 
        while(true){
            dfs(1,depth);
            if (flag) break;
            depth++;
        }
        printf("%d",a[1]);
        for (int i=2;i<=depth;i++) printf(" %d",a[i]);
        printf("\n");
    }
    return 0;
}

 

你可能感兴趣的:(【poj2248】Addition Chains)