D. Yet Another Problem On a Subsequence
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
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.
Examples
inputCopy
3
2 1 1
outputCopy
2
inputCopy
4
1 1 1 1
outputCopy
7
我们用dp[i]dp[i]表示以第ii位开始的good sequences的数目。
首先使dp[n+1]=1,因为最后一位不选也是一种方案,有利于之后dp的转移。
我们发现两个good sequence首尾相连还是一个good sequence。
所以利用这一个性质,枚举j从i+a[i]+1到n+1。由于是求子序列的数目,所以只需在j−i−1个数字当中任选a[i]个就可以了。组合数的结果乘上dp[i]就可以了。
#include <bits/stdc++.h>
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lowbit(x) x&-x
#define pb push_back
#define MP make_pair
#define clr(a) memset(a,0,sizeof(a))
#define _INF(a) memset(a,0x3f,sizeof(a))
#define FIN freopen("in.txt","r",stdin)
#define fuck(x) cout<<"["<<x<<"]"<<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>pii;
typedef pair<ll,ll>pll;
typedef vector<int> VI;
const int MX=1000+5;
const int mod=998244353;
int n;
int a[MX];
ll dp[MX],res[MX];
ll C[MX][MX];
void init(){
C[0][0] = 1;
for(int i = 1;i < MX;i++){
C[i][0] = C[i][i] = 1;
for(int j = 1;j < i;j++){
C[i][j] = (C[i-1][j-1] + C[i-1][j])%mod;
}
}
}
int main(){
init();
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=n;i>=1;i--){
if(a[i]>0 && a[i]+i<=n){
for(int j=a[i]+i;j<=n;j++){
dp[i]=(dp[i]+(C[j-i-1][a[i]-1]*(1+res[j+1])%mod))%mod;
}
}
res[i]=(res[i+1]+dp[i])%mod;
}
printf("%lld\n",res[1]%mod);
return 0;
}