bzoj 2796: [Poi2012]Fibonacci Representation 记忆化搜索

来源:互联网 发布:mysql set 动态参数 编辑:程序博客网 时间:2024/06/04 19:03

题意

给出一个正整数x,问x最少能由多少个Fibonacci数加减算出。
例如1070=987+89-5-1,因此x=1070时答案是4。
T<=10,x<=4*10^17

分析

都是套路~~
设w[i]表示x=i时的答案,找到最大的l满足f[l] < x,然后w[i]=min(w[x-f[l]],w[f[l+1]-x])+1。记忆化搜索一下即可。
证明的话。。。还不会。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<map>using namespace std;typedef long long LL;int mx;LL f[105],n;map<LL,int> w;int dfs(LL x){    if (w[x]) return w[x];    int l=1,r=mx;    while (l<=r)    {        int mid=(l+r)/2;        if (f[mid]<=x) l=mid+1;        else r=mid-1;    }    l--;    if (f[l]==x) return w[x]=1;    else return w[x]=min(dfs(x-f[l]),dfs(f[l+1]-x))+1;}int main(){    f[1]=f[2]=1;    for (int i=3;f[i-1]<=(LL)4e17;i++,mx=i) f[i]=f[i-1]+f[i-2];    int T;    scanf("%d",&T);    while (T--)    {        scanf("%lld",&n);        printf("%d\n",dfs(n));    }    return 0;}
原创粉丝点击