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;
}