number number number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 26 Accepted Submission(s): 13
Problem Description
We define a sequence
F
:
⋅
F
0
=0,F
1
=1
;
⋅
F
n
=F
n−1
+F
n−2
(n≥2)
.
Give you an integer k
, if a positive number
n
can be expressed by
n=F
a
1![]()
+F
a
2![]()
+...+F
a
k![]()
![]()
where
0≤a
1
≤a
2
≤⋯≤a
k![]()
, this positive number is
mjf−good
. Otherwise, this positive number is
mjf−bad
.
Now, give you an integer k
, you task is to find the minimal positive
mjf−bad
number.
The answer may be too large. Please print the answer modulo 998244353.
⋅
⋅
Give you an integer k
n=F
Now, give you an integer k
The answer may be too large. Please print the answer modulo 998244353.
Input
There are about 500 test cases, end up with EOF.
Each test case includes an integer k
which is described above. (
1≤k≤10
9![]()
)
Each test case includes an integer k
Output
For each case, output the minimal
mjf−bad
number mod 998244353.
Sample Input
1
Sample Output
4
Source
【题意】:
给出一个数k,问用k个斐波那契数相加,得不到的数最小是几。
【解析】:
暴力写了下前几项,发现有规律。f[n] = f[n-1]*3 - f[n-2] + 1
然后用矩阵快速幂可以直接得出答案。
【代码】
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define mset(a,i) memset(a,i,sizeof(a))
using namespace std;
typedef long long ll;
const int mod=998244353;
ll qpow(ll n,ll m){n%=mod;ll ans=1;while(m){if(m%2)
ans=(ans*n)%mod;m/=2;n=(n*n)%mod;}return ans;}
struct zhen{
int r,c;//行列始于1
ll a[16][16];
zhen(int R=0,int C=0){
memset(a,0,sizeof(a));
r=R;c=C;
}
};
zhen operator*(zhen A,zhen B)//矩阵A*B
{
zhen C(A.r,B.c);
for(int i=1;i<=A.r;i++)
for(int j=1;j<=B.c;j++)
for(int k=1;k<=A.c;k++){
C.a[i][j]+=((A.a[i][k]+mod)*(mod+B.a[k][j]))%mod;
C.a[i][j]%=mod;
}
return C;
}
zhen qpow(zhen A,ll m)//方阵A的m次幂
{
zhen ans(A.r,A.c);
for(int i=1;i<=A.r;i++) ans.a[i][i]=1;//单位矩阵
while(m)
{
if(m%2)ans=ans*A;
A=A*A;
m/=2;
}
return ans;
}
int main()
{
ll n;
while(cin>>n)
{
if(n==1){
puts("4");continue;
}
if(n==2){
puts("12");continue;
}
zhen A(3,3);//构造矩阵A
A.a[1][1]=3;
A.a[1][3]=A.a[2][1]=A.a[3][3]=1;
A.a[1][2]=-1;
//矩阵A构造完毕
//所以 Xn+1 = A^(n-2) * X3;
zhen X3(A.r,1),X;
X3.a[1][1]=12;
X3.a[2][1]=4;
X3.a[3][1]=1;
X=qpow(A,n-2)*X3;
ll ans=X.a[1][1];
cout<<ans%mod<<endl;
}
}
前几项打表的代码:
#include <stdio.h>
#include <string.h>
using namespace std;
typedef long long ll;
int dp[200][2000];
int main()
{
ll c[1100]={0,1,1};
for(int i=2;i<1020;i++)
c[i]=(c[i-1]+c[i-2]);
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i = 0; i <= 40; i++) //枚举总类
{
for (int num = 1; num <= 40; num++) //枚举个数
{
for (int j = c[i]; j <= 1000; j++) //枚举容量
{
dp[num][j] += dp[num - 1][j - c[i]];
}
}
}
for(int i=0;i<=40;i++)
for(int j=1;j<=1000;j++)
if(dp[i][j]==0)
{
printf("%d\n",j);break;
}
return 0;
}