【bzoj2796】 [Poi2012]Fibonacci Representation

【bzoj2796】 [Poi2012]Fibonacci Representation

Description

Fib数列0,1,1,2,3,5,8,13,21。

给出一个数字,用FIB数列各项加加减减来得到。例如

10=5+5

19=21-2

17=13+5-1

1070=987+89-5-1

Input

In the first line of the standard input a single positive integer is given (1 <=P<=10) that denotes the number of queries. The following lines hold a single positive integer K each 1<=K<=10^17.

Output

For each query your program should print on the standard output the minimum number of Fibonacci numbers needed to represent the number k as their sum or difference.

Sample Input

1
1070

Sample Output

4
题解
因为F[k]*2=F[k+1]+F[k-2],即存在最优解满足同一个FIB数出现次数不超过1
令l表示小等于n且最大的斐波那契数,r为其后一项,可以暴力或者二分求
dp(n) = min{ dp(n-l) , dp(r-n) } + 1
使用记忆化搜索
 
 1 #include<set>
 2 #include<map>
 3 #include<iostream>
 4 #include<cstdio>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 #include<algorithm>
 9 
10 #define ll long long
11 #define inf 2e18
12 using namespace std;
13 ll read()
14 {
15     ll x=0,f=1;char ch=getchar();
16     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
17     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 
21 int T,top;
22 ll n,f[1005];
23 map<ll,int>F;
24 
25 int solve(ll n)
26 {
27     if(F[n])return F[n];
28     int b=lower_bound(f,f+top,n)-f;
29     if(f[b]==n)return 1;
30     return F[n]=min(solve(n-f[b-1]),solve(f[b]-n))+1;
31 }
32 int main()
33 {
34     f[0]=1;f[1]=1;
35     for(int i=2;f[i-1]<=inf;i++,top++)
36         f[i]=f[i-1]+f[i-2];
37     T=read();
38     while(T--)
39     {
40         n=read();
41         printf("%d\n",solve(n));
42     }
43 }

 

posted @ 2017-12-29 10:19  Kaiser-  阅读(185)  评论(0编辑  收藏  举报