打表找规律+矩阵快速幂

来源:互联网 发布:初学钢琴软件 编辑:程序博客网 时间:2024/05/23 21:40

number number number


题意:

给出斐波那契数组的定义,F0=0,F1=1;Fn=Fn1+Fn2 (n2).

给定一个k,求出不能由k个斐波那契数组成的最小的数。


数据范围:

多组输入,由EOF结束。1k109


时间:1s


题解:

首先打一个表,找出前面几项的结果,然后就能发现规律。


打表代码:

#include<iostream>#include<stdio.h>#include<string.h>const int maxn = 100000;const int mod = 998244353;typedef long long ll;using namespace std;ll n,k,f[maxn+5];int p[maxn];int main(){    f[0] = 0, f[1] = 1;    for(int i=2; i<=30; i++) f[i]=f[i-1]+f[i-2];    for(int i=1; i<=20; ++i)printf("%d %d\n",i,f[i]);    printf("\n");    int maxp=0;    for(int i=1; i<=300; i++)    {        p[i]=i;        for(int j=1; f[j]<=i; j++)            p[i]=min(p[i],p[i-f[j]]+1);        printf("%d %d",i,p[i]);        if(maxp<p[i])        {            printf("--------------");            maxp=p[i];        }        puts("");    }    return 0;}


AC代码:

#include <iostream>#include <stdio.h>#include <string.h>#define LL long longusing namespace std;const LL mod=998244353;const int maxn=2;struct Mat{    LL mp[maxn][maxn];} res,A;Mat Mul(Mat a,Mat b){    int n=2;    Mat c;    memset(c.mp,0,sizeof(c.mp));    for(int i=0; i<n; ++i)        for(int j=0; j<n; ++j)            for(int k=0; k<n; ++k)            {                c.mp[i][j]+=(a.mp[i][k]*b.mp[k][j])%mod;                c.mp[i][j]%=mod;            }    return c;}LL Pow(LL k){    while(k>0)    {        if(k&1) res=Mul(A,res);        A=Mul(A,A);        k/=2;    }    return ((res.mp[0][0]-1)%mod+mod)%mod;}void Init(){    res.mp[0][0]=res.mp[1][1]=1;    res.mp[0][1]=res.mp[1][0]=0;    A.mp[0][0]=A.mp[0][1]=A.mp[1][0]=1;    A.mp[1][1]=0;}int main(){    LL k;    while(scanf("%lld",&k)!=EOF)    {        Init();        printf("%lld\n",Pow(k*2+2));    }    return 0;}




阅读全文
0 0
原创粉丝点击