The sequence of integers a1,a2,…,aka1,a2,…,ak is called a good array if a1=k−1a1=k−1 and a1>0a1>0 . For example, the sequences [3,−1,44,0],[1,−99][3,−1,44,0],[1,−99] are good arrays, and the sequences [3,7,8],[2,5,4,1],[0][3,7,8],[2,5,4,1],[0] — are not.
A sequence of integers is called good if it can be divided into a positive number of good arrays. Each good array should be a subsegment of sequence and each element of the sequence should belong to exactly one array. For example, the sequences [2,−3,0,1,4][2,−3,0,1,4] , [1,2,3,−3,−9,4][1,2,3,−3,−9,4] are good, and the sequences [2,−3,0,1][2,−3,0,1] , [1,2,3,−3−9,4,1][1,2,3,−3−9,4,1] — are not.
For a given sequence of numbers, count the number of its subsequences that are good sequences, and print the number of such subsequences modulo 998244353.
Input
The first line contains the number n (1≤n≤103)n (1≤n≤103) — the length of the initial sequence. The following line contains nn integers a1,a2,…,an (−109≤ai≤109)a1,a2,…,an (−109≤ai≤109) — the sequence itself.
Output
In the single line output one integer — the number of subsequences of the original sequence that are good sequences, taken modulo 998244353.
题解:
分为 good array 和good sequence 设为i之后的答案数。 即为所求。
对于good array
对于good sequence
所以 。 即为所求。
这里我用了逆元求组合数。
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long ll;
using namespace std;
const int N=1100;
const int M=998244353;
int n,a[N];
ll fac[N],inv[N],f[N],ans;
ll pow_mod(ll a,int b){
ll ans=1;a=a%M;
while(b){
if(b&1) ans=ans*a%M;
a=a*a%M;b>>=1;
}
return ans%M;
}
void pre(){
int maxn=1e3+5;fac[0]=1;
for(int i=1;i<=maxn;i++) fac[i]=fac[i-1]*i%M;
inv[maxn]=pow_mod(fac[maxn],M-2);
for(int i=maxn-1;i>=0;i--) inv[i]=inv[i+1]*(i+1)%M;
}
ll calc(int n,int m){
if(n<m) return 0;
return fac[n]*inv[n-m]%M*inv[m]%M;
}
int main(){
// freopen("D.in","r",stdin);
pre();
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
ll ans=0;
for(int i=n;i>=1;i--){
if(a[i]<=0||n-i<a[i]) continue;
f[i]=calc(n-i,a[i]);
for(int j=i+a[i]+1;j<=n;j++){
if(a[j]<=0 ) continue;
f[i]=(f[i]+f[j]*calc(j-i-1,a[i])%M)%M;
}
ans=(ans+f[i])%M;
}
printf("%lld\n",ans);
return 0;
}