设f[i]是以i为开头的好子序列的个数
那么有$f[i]=sumlimits_{j=i+a[i]+1}^{N+1}{f[j]*C_{j-i-1}^{a[i]}}$(设f[N+1]=1)就是以i为开头选出一个好子数组的每种情况*再把它拼到后面的一个好子序列的数量
随便用什么方法预处理一下组合数就行了
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=1e3+10,P=998244353; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 ll f[maxn],c[maxn][maxn]; 16 int a[maxn],N; 17 18 int main(){ 19 int i,j,k; 20 N=rd(); 21 for(i=1;i<=N;i++) a[i]=rd(); 22 23 c[1][0]=c[1][1]=1; 24 for(i=2;i<=N;i++){ 25 for(j=0;j<=i;j++){ 26 if(j) c[i][j]=(c[i-1][j-1]+c[i-1][j])%P; 27 else c[i][j]=1; 28 } 29 } 30 31 for(i=N;i;i--){ 32 if(a[i]<=0||i+a[i]>N) continue; 33 int s=0; 34 for(j=N;j>=i+a[i]+1;j--){ 35 f[i]=(f[i]+c[j-i-1][a[i]]*f[j])%P; 36 } 37 f[i]=(f[i]+c[N-i][a[i]])%P; 38 } 39 ll ans=0; 40 for(i=1;i<=N;i++) ans+=f[i],ans%=P; 41 printf("%d ",ans); 42 return 0; 43 }