BZOJ2796/POI2012 Fibonacci Representation

来源:互联网 发布:渡劫 知乎 编辑:程序博客网 时间:2024/05/16 08:29

Task
Fib数列0,1,1,2,3,5,8,13,21。
给出一个数字,用FIB数列各项加加减减来得到。例如
10=5+5
19=21-2
求出通过加减得到K的最少项数.
1<=K<=10^17.

Solution
有一个贪心的思路,每次找到离K最近的两项f(i),f(i+1),再把问题转化为求K-f(i),f(i+1)-K即可.用计划搜索优化.我是将10^7以内的数字直接用数组存下来,不过发现效率远没有用map存下所有值的高.T_T

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<vector>#define ll long long#include<queue>using namespace std;inline void rd(int &res){    res=0;char c;    while(c=getchar(),c<48);    do res=(res<<1)+(res<<3)+(c^48);    while(c=getchar(),c>=48);}inline void print(ll x){    if(!x)return ;    print(x/10);    putchar((x%10)^48);}inline void sc(ll x){    if(x<0){x=-x;putchar('-');}    print(x);    if(!x)putchar('0');    putchar('\n');}const ll M=1e18;const int N=1e7+3e6+5;ll A[200],K;int tot=89,f[N];void Init(){    A[1]=1;A[2]=1;    for(int i=3;i<tot;i++)A[i]=A[i-1]+A[i-2];}int solve(ll x,int r){    if(x<N&&~f[x])return f[x];    int ans,a=lower_bound(A,A+r,x)-A;    if(A[a]==x)ans=1;    else ans=1+min(solve(x-A[a-1],a-2),solve(A[a]-x,a-2));    if(x<N)f[x]=ans;    return ans;}int main(){    int i,j,cas,a,b,mx=0,m=0;    Init();    memset(f,-1,sizeof(f));    scanf("%d",&cas);    while(cas--){        cin>>K;        printf("%d\n",solve(K,tot));    }    return 0;}
0 0
原创粉丝点击