2796: [Poi2012]Fibonacci Representation 思路题 map+记忆化搜索

来源:互联网 发布:may it be mv 编辑:程序博客网 时间:2024/06/05 00:22

POI的题果然神。。不会做啊。。


f(n)表示斐波那契数列的第n项,则有:

f(n)=f(n1)+f(n2)

f(n+1)=f(n)+f(n1)

联立得:
2f(n)=f(n+1)+f(n2)

所以如果一个数出现了两次,可以把它转化为两个不同的数,所以总存在一个合法的解,使得每个数出现最多一次。
我们用F(n)表示结果为n时的答案,令f(b)表示<=n的第一个斐波那契数列中的数。
f(b)=n的时候,答案为F(n)=1
否则F(n)=min(F(nf(b)),F(f(b+1)n))+1,然后可以记忆化搜索。数字比较大用map。

#include<iostream>#include<cstdio>#include<queue>#include<set>#include<map>#include<algorithm>#define inf 2e18#define ll long long using namespace std;map<ll,int> F;ll n,f[1005];int top;inline ll read(){    ll a=0,f=1; char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}    return a*f;}int solve(ll x){    if (F[x]) return F[x];    int b=lower_bound(f,f+top,x)-f;    if (f[b]==x) return 1;    return F[x]=min(solve(x-f[b-1]),solve(f[b]-x))+1;}int main(){    f[0]=f[1]=1;    for (int i=2;f[i-1]<=inf;i++,top++)        f[i]=f[i-1]+f[i-2];    int testcase=read();    while (testcase--)    {        n=read();        printf("%d\n",solve(n));    }    return 0;}
0 0
原创粉丝点击