首页 > 代码库 > UVA529- Addition Chains(迭代+DFS)

UVA529- Addition Chains(迭代+DFS)

题目链接

题意:给一个数n,要你找出一个以n为结尾的序列,使得这个序列中的任意一个数(1除外),能由序列中的两个数(可以相同)相加得到。求最短的序列,如有多种组合,任意输出一个。

思路:要迭代+DFS,首先我们可以得到要使序列尽量短的话,那么n最好是能由n/2相加得到,所以我们就可以得到最小深度depth,以depth为基础,进行深搜,如果满足的话就输出,如果不符合的话,再到一下个深度的depth+1进行深搜,直到找到为止。这里要注意剪枝,当前数cur向下一直取最大值,如果都不能超过n的话,就可以直接跳出来了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN = 10005;

int arr[MAXN];
int n, depth, flag;

void init() {
    memset(arr, 0, sizeof(arr));
    arr[0] = 1;
    depth = 0;
    int temp = 1;
    while (temp < n) { 
        temp = temp << 1;
        depth++;
    }
}

int dfs(int cur) {
    if (cur >= depth) {
        if(arr[cur] == n)
            return true;
        return false;
    }
    if (arr[cur] << (depth - cur + 1) < n)
        return false;
    for (int i = 0; i <= cur; i++) 
        for (int j = i; j <= cur; j++) {
            int sum = arr[i] + arr[j];
            if (sum > arr[cur] && sum <= n) {
                arr[cur + 1] = sum;
                if (dfs(cur + 1))
                    return true;
            } 
        }  
    return false;
}

int main() {
    while (scanf("%d", &n) && n) {
        init();
        while (!dfs(0)) 
            depth++; 
        printf("%d", arr[0]);
        for (int i = 1; i <= depth; i++) 
            printf(" %d", arr[i]);  
        printf("\n");
    }    
    return 0;
}