You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include<bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
const int N = 10010;
|
|
|
|
|
|
|
|
|
|
int n; //输入的加法链最后一个数字
|
|
|
|
|
int ans[N]; //结果数组
|
|
|
|
|
int depth; //迭代加深的最后一个索引位置,不要理解为深度层,比如 a[0] a[1] a[2] ,那么depth=2,按深度说是3
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:迭代加深,在当前的depth深度下,尝试找出答案
|
|
|
|
|
* @param k 第几个数字
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
bool dfs(int k) {
|
|
|
|
|
//如果走过规定好的步骤,回头看一眼,如果最后一次放入的是n,表示成功找到,否则就是失败
|
|
|
|
|
if (k > depth)return ans[k - 1] == n;
|
|
|
|
|
|
|
|
|
|
//最优化剪枝:后面每一项最多是前一项的2倍
|
|
|
|
|
//肯定无法到达的,提前干掉,可以极大提高性能!
|
|
|
|
|
//这个优化太棒了!
|
|
|
|
|
if (ans[k - 1] * (1 << (depth - k + 1)) < n)return false;
|
|
|
|
|
|
|
|
|
|
//枚举k之前的所有数字,两两一组
|
|
|
|
|
for (int i = 0; i < k; i++)
|
|
|
|
|
for (int j = i; j < k; j++) { //双重循环保证了可以遍历出两两的所有组合情况
|
|
|
|
|
int t = ans[i] + ans[j]; //两两之和
|
|
|
|
|
if (t > ans[k - 1]) {
|
|
|
|
|
ans[k] = t; //将和加入到目标数组中,完成本位置的填充
|
|
|
|
|
//尝试进行下一个位置的填充
|
|
|
|
|
if (dfs(k + 1))return true; //如果找到答案,就终止;否则需要继续探索之
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
//优化输入
|
|
|
|
|
ios::sync_with_stdio(false);
|
|
|
|
|
//加法链第一个数字是1
|
|
|
|
|
ans[0] = 1;
|
|
|
|
|
//读取多组数据
|
|
|
|
|
while (cin >> n, n) {
|
|
|
|
|
//遍历每个可能的到达的索引号,在找到第一个解后退出
|
|
|
|
|
for (depth = 0;; depth++) {
|
|
|
|
|
//如果在当前索引号下就能成功符合要求,表示找到了最短路径,退出就可以了
|
|
|
|
|
if (dfs(1)) { //a[0]值是1,从a[1]开始尝试
|
|
|
|
|
//找到答案输出
|
|
|
|
|
for (int i = 0; i <= depth; i++) {
|
|
|
|
|
//结果
|
|
|
|
|
printf("%d", ans[i]);
|
|
|
|
|
//万恶的UVA,每一行最后如果带空格还WA,还需要判断一下才行
|
|
|
|
|
if (i < depth)printf(" ");
|
|
|
|
|
}
|
|
|
|
|
//每组数完事换行
|
|
|
|
|
printf("\n");
|
|
|
|
|
//找到就结束,迭代加深的套路思想噢~
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|