题目地址:

  http://codeforces.com/contest/1000/problem/D

题意:

  输入 $n$,给  $n$ 个数字,问有多少个子串(子串可以不连续)满足 good sequence

  如果一个array的长度为k,且array的第一个元素array[1]为k-1(array[1] > 0),则称这个array为good array,由一个或多个array连接组成的sequence称为good sequence 

必要思考:

  1.如何判断从一个数开始有多少个 good array 呢,这个简单直接用组合数 C 就可以实现

  2.如何判断从一个数字开始有多少good sequence 呢,这个就需要判断从这个数开始有多少个 good array ,并且其后从什么位置可以开始接其他起点的 good array。由于需要往后遍历,所以需要从后往前计算,一维DP

代码:

#include<bits/stdc++.h>
using namespace std;
long long a[1000+7];
long long dp[1000+7];
long long c[1005][1005];
void db()
{
    memset(c,0,sizeof(c));
    c[0][0]=1;
    for(int i=0;i<=1000;i++)
    {
        c[i][0]=1;
        for(int j=1;j<=i;j++)
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%998244353;
    }
}
int main()
{
    db();
    int n;cin>>n;
    memset(a,0,sizeof(a));
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
        cin>>a[i];
    long long ans=0;
    dp[n+1]=1;//表示一个也不接时候就是其本身的系数
    for(int i=n;i>0;i--)
    {
        if(a[i]>0&&a[i]<=n-i)
        {
            for(int j=i+a[i]+1;j<=n+1;j++)//j 表示开始接入的起点
            {
                dp[i]=(dp[i]+c[j-i-1][a[i]]*dp[j])%998244353;
            }
            ans=(ans+dp[i])%998244353;
        }
    }
    cout<<ans%998244353<<endl;
}