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,…,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

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][a1,a2,a3] and [a2,a3][a2,a3].

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

算法分析:

题意:

给出一个长度为n的序列,问子序列(可以不连续)中存在多少个good sequence。

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

Solution:

dp[i] 表示以 a[i] 为首元素的good sequence的个数,故dp[i] 可以由 dp[i+1] 转化而来。

首先枚举起点 i 的位置,即从 n-1 ~ 1 倒序枚举(由于array长度最少为2,所以从n-1开始),那么对于每个当前good array的起始元素为 i 位置,假定后面可以接的其它的good array的起始元素为 a[j],对于序列长度最少为 a[i] + 1了来说,那么 j 的起始位置就是 i + a[i] + 1,终止位置为 n + 1(j = n+1 时表示此时后面不再接其它的good array),可以得出,对于当前的array来说,他的组成元素是从 j - i - 1 个元素中任选 a[i] 个。对于可选的元素为j - i - 1 个解释:容易得出,在 j 位置与 i 位置之间,一共有 j - i + 1 个元素,由于元素 a[i] 本身已经确定为当前array的首元素,而 a[j] 也已经确定为是下一个array的首元素,所以 a[i] 和 a[j] 都不能选,所以需要从 j - i - 1 个元素中选取 a[i] 个。

可以得出转移方程为:

dp[i] = c[ j - i -1][a[i] ] * dp[j]。(组合数c[i][j] 表示从 j - i - 1 这些个元素中任取出a[i]个元素)

上面思路参考:https://blog.csdn.net/Jasmineaha/article/details/81176012

确实妙,从后往前枚举,可以避免很多东西,比赛时最后还有二十分钟才看的这道题,确实着急了些。本人对DP的状态转移方程做一些解释,大家想一下,好数列可以分成两种:

1.如果一个array的长度为k,且array的第一个元素array[1]为k-1(array[1] > 0),则称这个array为good array。

2.由一个或多个array连接组成的sequence称为good sequence 。

第1个好算枚举,但第2个不好算,上面的思路就很好的解决了这个问题,dp[i] = c[ j - i -1][a[i] ] * dp[j],这就是为什么*dp[j]的原因。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <stack>
#define mst(a, b) memset(a, b, sizeof(a))
#define rush() int T; cin >> T; while(T--)
using namespace std;
typedef long long LL;
const int MaxN = 1e5 + 5;
const int INF = 0x3f3f3f3f;
const LL Mod = 998244353;
const double eps = 1e-9;LL a[1005], c[1005][1005];
LL dp[1005];
int n;void init() {cin >> n;for(int i = 1; i <= n; i++) {for(int j = 1; j <= n; j++) {if(j == 1) c[i][j] = i;else c[i][j] = (c[i-1][j] + c[i-1][j-1]) % Mod; //预处理组合数结果}}for(int i = 1; i <= n; i++) cin >> a[i];
}
int main()
{init();dp[n + 1] = 1LL; //当前array 后面不接其它的arrayLL sum = 0LL;for(int i = n - 1; i >= 1; i--) {if(a[i] <= 0) continue;for(int j = i + a[i] + 1; j <= n + 1; j++) {dp[i] += c[j-i-1][a[i]] * dp[j];dp[i] %= Mod;}sum =(sum + dp[i]) % Mod; //答案为每个i位置上可能的array数目之和}cout << sum << endl;return 0;
}

CodeForces - 1000D D. Yet Another Problem On a Subsequence 好题相关推荐

  1. CodeForces - 1000D:Yet Another Problem On a Subsequence (DP+组合数)

    CodeForces - 1000D:Yet Another Problem On a Subsequence (DP+组合数) 题目大意:这题目啊,贼难理解- 定义一个数列是"好的&quo ...

  2. Codeforces Round #555 (Div. 3), problem: (C2) Increasing Subsequence (hard version)【贪心+撞到南墙也不回头】

    题目链接 题目大意 复杂版大意是我们可以从左右两端每次拿走一个数,一直拿,不过要满足一个条件,每次拿的数要保证严格递增(即从小到大然后不会有相同的情况) 复杂版的话是会有相同的数字出现 在题解中正式说 ...

  3. D - Yet Another Problem On a Subsequence CodeForces - 1000D (DP,组合数学)

    D - Yet Another Problem On a Subsequence CodeForces - 1000D The sequence of integers a1,a2,-,aka1,a2 ...

  4. Codeforces 1000D Yet Another Problem On a Subsequence 动态规划

    D. Yet Another Problem On a Subsequence time limit per test 2 seconds memory limit per test 256 mega ...

  5. Codeforces Round #698 (Div. 2)(A ~ F)6题全,超高质量题解)【每日亿题】2021/2/4

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 [每日亿题]Codeforces Round #698 (Div. 2)(A ~ F)6题全,超 ...

  6. CodeForces - 1000D Yet Another Problem On a Subsequence(动态规划+组合数学)

    题目链接:点击查看 题目大意:给出n个数字组成的序列,现在规定"好数组"指的是一个连续序列a1,a2,...ak的a1=k-1,再规定"好序列"是可以分为若干个 ...

  7. Codeforces 1000D Yet Another Problem On a Subsequence

    题目:点击打开链接 题意:定义一个数列是"好的":第一个数字a[0]为数列长度+1.定义一个数列的子序列是"好的":这个子序列能分割成几个"好的&qu ...

  8. CodeForces - 1000D Yet Another Problem On a Subsequence

    题面在这里! 好智障的一个dp啊,一段开头的数字相当于下面要跟多少个数,直接滚动数组dp就行了... #include<bits/stdc++.h> #define ll long lon ...

  9. Yet Another Problem On a Subsequence CodeForces - 1000D (组合计数)

    大意:定义一个长为$k>1$且首项为$k-1$的区间为好区间. 定义一个能划分为若干个好区间的序列为好序列. 给定序列$a$, 求有多少个子序列为好序列. 刚开始一直没想出来怎么避免重复计数, ...

最新文章

  1. C++中的类属(泛型)机制——模板
  2. 炸!亿级数据DB秒级平滑扩容!!!
  3. 熊市利好,Bit-Z推出币圈最高返佣50%
  4. .net获取地址栏中的url
  5. 启动rabbitmq,提示ERROR: node with name rabbit already running on localhost(亲测)
  6. strstr和memcmp函数的实现
  7. learning python学习小记(一)
  8. ifconfig命令找不到_02. Linux命令之查看网络连接
  9. 信息学奥数一本通(1170:计算2的N次方)
  10. django分页的东西, 不详细, 但是也足够了。
  11. liferay 6.2 主题开发
  12. scala类的序列化_Scala序列理解,通用类和内部类示例
  13. 网易互娱基于 Flink 的支付环境全关联分析实践
  14. 显著性目标检测matlab代码_YOLO v3 目标检测终篇(附完整 GitHub 代码)
  15. 沙龙回顾|你pick的程序小哥可以C位出道了吗?(内含PPT和演讲稿福利哦!)...
  16. vue中使用leaflet加载地图影像并拾取坐标点
  17. vue回到顶部(常用)
  18. 雾霾不散,课就不得不停?
  19. JAVA记忆翻牌游戏制作
  20. html5 龙,百度移动可搜龙点睛 技术创新挺进HTML5元年

热门文章

  1. 融易宝项目管理平台前台搭建
  2. MD5 hash碰撞实现解密
  3. Python计算图片之间的相似度
  4. HarmonyOS之AI能力·语音识别技术
  5. 数学建模入门例题python_Python 数学建模极简入门(一)
  6. File size exceeds....(文件大小超过限制处理)
  7. 雷达图像中地物目标的极化信息
  8. 车辆逆行识别检测系统 opencv
  9. 达梦DM数据库网页数据维护工具
  10. svn - 冲突及解决方案