number number number
题意:
给出斐波那契数组的定义,⋅F0=0,F1=1;⋅Fn=Fn−1+Fn−2 (n≥2).
给定一个k,求出不能由k个斐波那契数组成的最小的数。
数据范围:
多组输入,由EOF结束。1≤k≤109
时间: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 long using 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; }