cf1000D Yet Another Problem On a Subsequence (dp)

设f[i]是以i为开头的好子序列的个数

那么有$f[i]=\sum\limits_{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\n",ans);
42     return 0;
43 }

猜你喜欢

转载自www.cnblogs.com/Ressed/p/9863311.html