题意:给一个数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; }
UVA529- Addition Chains(迭代+DFS)
时间: 2024-11-11 03:40:27