题目背景
无
题目描述
已知任意一个正整数都可以拆分为若干个斐波纳契数,现在,让你求出n的拆分方法
输入输出格式
输入格式:
一个数t,表示有t组数据
接下来t行,每行一个数n(如题)
输出格式:
t行,每行一个字符串,表示拆分方法(格式:n=a1+a2+a3+..+an),要求从小到大输出
输入输出样例
输入样例#1:
input1:1
1
input2:1
10
输出样例#1:
output1:1=1;
output2:10=2+8;
说明
若有多组数据,以个数最小的为准,若仍有多组,输出右边尽量大的一组
对于100%的数据 t<=1000 1<=n<=10^9
【分析】
这题应该是搜索…
加一个最优性剪枝就能过(数据太水)
【代码】
//斐波那契拆分
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
int a[105],ans[105],l[105];
int n,t,tot,siz;
inline void dfs(int now,int up,int dep)
{
int i,j;
if(now==0)
{
if(dep-1<siz)
{
siz=dep-1;
for(i=dep-1;i>=1;i--) ans[i]=l[i];
return;
}
for(i=dep-1;i>=1;i--)
if(l[i]<ans[i]) return;
for(i=dep-1;i>=1;i--) ans[i]=l[i];
}
if(dep>siz) return;
for(i=up;i>=1;i--)
if(a[i]<=now)
l[dep]=a[i],dfs(now-a[i],i,dep+1);
}
int main()
{
int i,j;
scanf("%d",&t);
a[1]=1,a[2]=2;
fo(i,3,100)
{
a[i]=a[i-1]+a[i-2];
if(a[i]>1e9) {tot=i;break;}
}
while(t--)
{
M(ans);siz=1e8;
scanf("%d",&n);
fo(i,1,tot) if(a[i]>n) break;
dfs(n,i-1,1);
printf("%d=",n);
for(i=siz;i>=1;i--)
{
printf("%d",ans[i]);
if(i!=1) printf("+");
}
printf("\n");
}
return 0;
}