Educational Codeforces Round 46 D. Yet Another Problem On a Subsequence (组合数+dp)

D. Yet Another Problem On a Subsequence

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

The sequence of integers a1,a2,…,ak

is called a good array if a1=k−1 and a1>0. For example, the sequences [3,−1,44,0],[1,−99] are good arrays, and the sequences [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]

, [1,2,3,−3,−9,4] are good, and the sequences [2,−3,0,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)

— the length of the initial sequence. The following line contains n integers 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

Input

Copy

3
2 1 1

Output

Copy

2

Input

Copy

4
1 1 1 1

Output

Copy

7

Note

In the first test case, two good subsequences — [a1,a2,a3]

and [a2,a3]

In the second test case, seven good subsequences — [a1,a2,a3,a4],[a1,a2],[a1,a3],[a1,a4],[a2,a3],[a2,a4]

and [a3,a4].

题目大意:如果一个序列的第一个数刚好等于序列的长度-1,那么这个序列就是一个好的序列。同时如果多个好的序列连在一起,连成后的序列也是好的序列。

现在给出一个数列a,问a的子序列有多少个是好的序列。

题目思路:对于每一个非组合而成的序列,由于我们只需要考虑第一个数字的大小。当a[i]为序列第一位的时候,我们可以枚举以j 为结尾的情况,那么此时的方案数就为C(j-i-1,a[i]-1),即除去第一位和最后一位,在区间[i+1,j-1]内选出a[i]-1个数的方案数。

但由于本题有组合的情况,我们可以倒着进行dp,dp[i]表示以 i 为序列起点的所有方案数,再用一个数组res来记录后缀和,res[i]表示以i~n为序列起点的所有方案数,那么就可以推出状态转移方程为

dp[i]=dp[i]+C(j-i-1,a[i-1)*(1+res[j+1])

这样最终的答案就是res[1]。

具体实现看代码:

#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],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;
}

猜你喜欢

转载自blog.csdn.net/Lee_w_j__/article/details/81462111