问题描述
XXX 每天都被无数的人膜拜,已经被连续膜拜了 n 天,他发现每天来膜拜自己的人数
是一个递增的数列。第一天只有一个人来膜拜,从第二天开始的每一天来膜拜 XXX 的人数
都是之前某两天的和。现在 XXX 告诉我们今天有 m 个人来膜拜自己,让我们求使被膜拜天数 n 最小的数列。如果有多组解,任意输出一种即可。
输入文件
一行,只有一个整数 m
输出文件
第一行输出 n。第二行输出数列,每两个数之间有且仅有一个空格。
输入样例
4
输出样例
3
1 2 4
样例解释
今天有 4 个人来膜拜,最少已经被连续膜拜了 3 天,第一天 1 人,第二天 2 人,第
三天(今天) 4 人。
数据范围
迭代深搜+剪枝
之前T了1个点,多交几次卡一下就过了
#include<cstdio>
#include<cstdlib>
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
#define rep_(i,a,b) for(int i=(a);i>=(b);i--)
typedef long long ll;
int m;
int ans[110];
int cnt=1;
bool IDdfs(int step)
{
if(ans[step-1]==m)//此处写成ans[step]
{
printf("%d\n",cnt);
_rep(i,1,cnt)
printf("%d%c",ans[i],i==cnt?'\n':' ');
exit(0);
}
if(step>cnt)return false;
rep_(i,step-1,1)rep_(j,step-1,i)
{
ans[step]=ans[i]+ans[j];
if((ans[step]<<(cnt-step))<m)break;//最大值在限制深度下的累加小于目标值
if(ans[step]<ans[step-1])break;//因递增序列
IDdfs(step+1);
}
return false;
}
int main()
{
scanf("%d",&m);
ans[1]=1;
while(!IDdfs(2))cnt++;
}