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.

64 lines
2.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}