CodeForces - 1000D D. Yet Another Problem On a Subsequence 好题
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 好题相关推荐
- CodeForces - 1000D:Yet Another Problem On a Subsequence (DP+组合数)
CodeForces - 1000D:Yet Another Problem On a Subsequence (DP+组合数) 题目大意:这题目啊,贼难理解- 定义一个数列是"好的&quo ...
- Codeforces Round #555 (Div. 3), problem: (C2) Increasing Subsequence (hard version)【贪心+撞到南墙也不回头】
题目链接 题目大意 复杂版大意是我们可以从左右两端每次拿走一个数,一直拿,不过要满足一个条件,每次拿的数要保证严格递增(即从小到大然后不会有相同的情况) 复杂版的话是会有相同的数字出现 在题解中正式说 ...
- 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 ...
- 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 ...
- Codeforces Round #698 (Div. 2)(A ~ F)6题全,超高质量题解)【每日亿题】2021/2/4
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 [每日亿题]Codeforces Round #698 (Div. 2)(A ~ F)6题全,超 ...
- CodeForces - 1000D Yet Another Problem On a Subsequence(动态规划+组合数学)
题目链接:点击查看 题目大意:给出n个数字组成的序列,现在规定"好数组"指的是一个连续序列a1,a2,...ak的a1=k-1,再规定"好序列"是可以分为若干个 ...
- Codeforces 1000D Yet Another Problem On a Subsequence
题目:点击打开链接 题意:定义一个数列是"好的":第一个数字a[0]为数列长度+1.定义一个数列的子序列是"好的":这个子序列能分割成几个"好的&qu ...
- CodeForces - 1000D Yet Another Problem On a Subsequence
题面在这里! 好智障的一个dp啊,一段开头的数字相当于下面要跟多少个数,直接滚动数组dp就行了... #include<bits/stdc++.h> #define ll long lon ...
- Yet Another Problem On a Subsequence CodeForces - 1000D (组合计数)
大意:定义一个长为$k>1$且首项为$k-1$的区间为好区间. 定义一个能划分为若干个好区间的序列为好序列. 给定序列$a$, 求有多少个子序列为好序列. 刚开始一直没想出来怎么避免重复计数, ...
最新文章
- C++中的类属(泛型)机制——模板
- 炸!亿级数据DB秒级平滑扩容!!!
- 熊市利好,Bit-Z推出币圈最高返佣50%
- .net获取地址栏中的url
- 启动rabbitmq,提示ERROR: node with name rabbit already running on localhost(亲测)
- strstr和memcmp函数的实现
- learning python学习小记(一)
- ifconfig命令找不到_02. Linux命令之查看网络连接
- 信息学奥数一本通(1170:计算2的N次方)
- django分页的东西, 不详细, 但是也足够了。
- liferay 6.2 主题开发
- scala类的序列化_Scala序列理解,通用类和内部类示例
- 网易互娱基于 Flink 的支付环境全关联分析实践
- 显著性目标检测matlab代码_YOLO v3 目标检测终篇(附完整 GitHub 代码)
- 沙龙回顾|你pick的程序小哥可以C位出道了吗?(内含PPT和演讲稿福利哦!)...
- vue中使用leaflet加载地图影像并拾取坐标点
- vue回到顶部(常用)
- 雾霾不散,课就不得不停?
- JAVA记忆翻牌游戏制作
- html5 龙,百度移动可搜龙点睛 技术创新挺进HTML5元年