Description
满足如下条件的序列 X(序列中元素被标号为 1, 2, 3, …, m )被称为“加成序列”:
X[1] = 1
X[m] = n
X[1] < X[2] < … < X[m−1] < X[m]
对于每个 k ( 2 ≤ k ≤ m ) 都存在两个整数 i 和 j ( 1 ≤ i, j ≤ k − 1 , i 和 j 可相等 ),使得 X[k] = X[i] + X[j]。
你的任务是:给定一个整数 n,找出符合上述条件的长度 m 最小的“加成序列”。
如果有多个满足要求的答案,只需要找出任意一个可行解。
Input
多组测试用例。
每组测试用例占据一行,包含一个整数 n ( 1 ≤ n ≤ 100 )。
当输入为单行的 0 时,表示输入结束。
Output
每个测试用例一行:一个满足需求的整数序列,数字之间用空格隔开
Sample Input
5
7
12
15
77
0Sample Output
1 2 4 5
1 2 4 6 7
1 2 4 8 12
1 2 4 5 10 15
1 2 4 8 9 17 34 68 77
迭代加深: 主要应用于在深搜分支和层数很多,但答案分布在较低层数的情况。为了避免在深搜时掉入一个错误分支中进行无穷无尽的搜索,因此在深搜时限制搜索层数。
代码如下:
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include<map>
#include<deque>
using namespace std;
const int N = 110;
int n;
int path[N];
bool dfs(int u, int depth) {
if (u > depth)return false;
if (path[u - 1] == n)return true;
int st[N] = { 0 };
for (int i = u - 1; i >= 0; i--)
for (int j = i; j >= 0; j--) {
int k = path[i] + path[j];
if (k <= path[u - 1] || k > n || st[k])continue;
path[u] = k;
st[k] = 1;
if (dfs(u + 1, depth))return true;
}
return false;
}
int main() {
while (scanf("%d", &n) && n) {
int depth = 1;
path[0] = 1;
while (!dfs(1, depth))depth++;//迭代加深常用模板
for (int i = 0; i < depth; i++)printf("%d ", path[i]);
printf("\n");
}
return 0;
}