题目
https://www.oitiku.com/simulate-contest/5/16
思路
考试的时候思考方向错了,以为是递推
我们可以枚举有多少个e,那么可以计算出来要多少个2
然后我们就可以用插板法来计算方案
但是要判断最后一个的边界
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+77;
int T,n;
int fac[N],unfac[N];
double e=exp(1);
const int mod=998244353;
int power(int x,int t){
int tot=1;
while(t){
if(t&1) tot=1ll*tot*x%mod;
x=1ll*x*x%mod;
t/=2;
}
return tot;
}
void add(int&x,int y){x=(x+y>=mod)?(x+y-mod):(x+y);}
int C(int x,int y){return 1ll*fac[x]*unfac[x-y]%mod*unfac[y]%mod;}
int main(){
freopen("A.in","r",stdin);
freopen("A.out","w",stdout);
scanf("%d",&T);n=10000000;
fac[0]=1;for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
unfac[n]=power(fac[n],mod-2);for(int i=n-1;i>=0;i--) unfac[i]=1ll*unfac[i+1]*(i+1)%mod;
while(T--){
scanf("%d",&n);
if(n<3){printf("1\n");continue;}
int ans=0;
for(int i=0;i*e<=n;i++)
for(int j=max((int)floor((n-i*e-3)/2),0);j*2+i*e<=n;j++){
if(n-i*e-j*2>=3) continue;
if(n-i*e-(j-1)*2>=3 && j) add(ans,C(i+j-1,j-1));
if(n-(i-1)*e-j*2>=3 && i) add(ans,C(i+j-1,i-1));
}
printf("%d\n",ans);
}
}