dp - 求符合题意的序列的个数

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

32 1 1

Output

2

Input

41 1 1 1

Output

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].

题意 : 给你一串数字,并按照题目叙述,给出一个好序列的定义,并且任意个好序列之间可以合并起来,问最终好序列的个数。

思路分析:

  dp[i] 表示以i位置开始的序列的最优解,倒着推一下就可以了, dp[i] += dp[j-i][i]*dp[j+1] (i+a[i] <= j <= n)

代码示例:

ll n;
ll a[1005];
ll c[1005][1005];

void init(){
    for(ll i = 1; i <= 1000; i++){
        c[i][0] = c[i][i] = 1;
        for(ll j = 1; j < i; j++){
            c[i][j] = (c[i-1][j]+c[i-1][j-1])%mod;
        }
    }
}
ll dp[1005];

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    init();

    cin >> n;
    for(ll i = 1; i <= n; i++){
        scanf("%lld", &a[i]);
    }
    dp[n+1] = 1;

    ll ans = 0;
    for(ll i = n-1; i >= 1; i--){
        ll p = i+a[i];
        if (a[i] <= 0) continue;
        for(ll j = p; j <= n; j++){
            dp[i] += (c[j-i][a[i]]*dp[j+1])%mod;
            dp[i] %= mod;
        }
        ans += dp[i];
        ans %= mod;
    }
    printf("%lld\n", ans);

    return 0;
}

原文地址:https://www.cnblogs.com/ccut-ry/p/9249354.html

时间: 2024-10-13 10:45:14

dp - 求符合题意的序列的个数的相关文章

hdu3709(求区间内平衡数的个数)数位dp

题意:题中平衡数的定义: 以一个位置作为平衡轴,然后左右其他数字本身大小作为重量,到平衡轴的距离作为全职,实现左右平衡(即杠杆原理平衡).然后为区间[x,y]内平衡数的个数. (0 ≤ x ≤ y ≤ 1018) 解法:数位dp.如果一个数的平衡数,那么它的平衡轴位置是确定的.原来一直尝试数位dp在dfs时候列举平衡轴的位置,后来才意识到可以提前枚举平衡轴位置,然后再dfs,这样比较好写.dp[mid][pre][wei];表示对称轴是mid,计算第pre个位置以后需要力矩大小wei的数的个数.

dp求顺序hdu1160

题意是仅仅求一次的顺序.先依照速度从大到小排序,速度想等到按体重增序排列. 然后基本就变成了求已定顺序序列的最长递增序列递增,跟那个求一致最大序列和的基本一致. dp[i]里存储的是到当前i最大的递增序列个数最大的数. dp[i+1]就是在a[i+1]大于前面的a[j]的情况下,dp[i+1]=dp[j]+1; 输出的就是从最大的dp[]值从后往前输出,所以用了个栈改成从前往后. 以为题意仅仅输出一个正确序列就好. 思路是从開始的结构体排序.打一打就想出来的.bug,调了一天.确定dp[]最大值

(hdu step 3.2.1)Max Sum(简单dp:求最大子序列和、起点、终点)

在写题解之前给自己打一下广告哈~..抱歉了,希望大家多多支持我在CSDN的视频课程,地址如下: http://edu.csdn.net/course/detail/209 题目: Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1390 Accepted Submission(s): 542   Problem Descrip

Codeforces 235B Let&#39;s Play Osu! (概率dp求期望+公式变形)

B. Let's Play Osu! time limit per test:2 seconds memory limit per test:256 megabytes You're playing a game called Osu! Here's a simplified version of it. There are n clicks in a game. For each click there are two outcomes: correct or bad. Let us deno

HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)

Problem Description Now you are back,and have a task to do: Given you a string s consist of lower-case English letters only,denote f(s) as the number of distinct sub-string of s. And you have some query,each time you should calculate f(s[l...r]), s[l

一个自然数在1700和1800之间,且被5除余3,被7除余4,被11除余6,求符合条件的数

昨天晚上看了一道逻辑题:一个自然数在1700和1800之间,且被5除余3,被7除余4,被11除余6,求符合条件的数.题目后面写着,有人看了几分钟便给出了答案.我很好奇,此人是如何解答的. 我自己先琢磨了下,拿笔算了半天,最后一个巧合的情况下,得到了答案.此题的一个关键且明显的推论是:能被5除余3的数,肯定最后一位是3或者8.那么接下来怎么推呢?我从网上搜集了答案. 方案1: 这个数被5除余3,则此数个位数为3或8, 设这个数十位为x,则此数可表达为1703+10x,或1708+10x当此数为17

求N!末尾的0的个数--找规律+递归

0\'s Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 计算整数n!(n的阶乘)末尾有多少个0. 输入 第一行输入一个数T代表测试数据个数(T<=20).接下来T行每行1个数代表n(0<=n< 2^31). 输出 对于每个测试数据输n!末尾有多少个0,每行输出一个结果. 示例输入 3 1 5 10 示例输出 0 1 2 提示 中国海洋大学第三届"朗讯杯"编程比赛高级组试题 声明(摘抄至某前辈)--

HDU 4405 Aeroplane chess (概率DP求期望)

题意:有一个n个点的飞行棋,问从0点掷骰子(1~6)走到n点需要步数的期望 其中有m个跳跃a,b表示走到a点可以直接跳到b点. dp[ i ]表示从i点走到n点的期望,在正常情况下i点可以到走到i+1,i+2,i+3,i+4,i+5,i+6 点且每个点的概率都为1/6 所以dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6  + 1(步数加一). 而对于有跳跃的点直接为dp[a]=dp[b]; #include<stdio.h>

ZOJ3329-One Person Game(概率DP求数学期望)

One Person Game Time Limit: 1 Second      Memory Limit: 32768 KB      Special Judge There is a very simple and interesting one-person game. You have 3 dice, namelyDie1, Die2 and Die3. Die1 hasK1 faces. Die2 has K2 faces.Die3 has K3 faces. All the dic