难点在于怎么想dp,我一开始想dp[i][j]代表前i个数挑j个能组成多少个good sebsequence,最后把dp[n][ 2到n ]加起来就行,但想不出来转移方程怎么做。后来想到我这么想是不对的,不应该先想状态怎么描述,而应该从题目入手去寻找一些性质(比如去思考good sequence的本质是什么),然后从得到的性质入手再去想状态。

那么good sequence的本质就是多个good array相连,一个good array后面加good sequence还是good sequence。那么能想到dp[i]表示从i-n,由i打头的good subsequence个数;这样dp[i]里每个情况都是由i开头的一个good array后面连good sequence。我们枚举good sequence可以接的位置是 j = i+a[i]+1 到 n,转移方程就是dp[i] = c[ j -i -1][ a[i] ] * dp[j] 【乘法原理】

最后考虑如果一个good array后面不接sequence的情况,那就是c[ n-i ][ a[i] ]个情况,我们可以把j放宽到n+1,并把dp[n+1]设成1来解决这个问题。

 1 #include<iostream>
 2 #include<map>
 3 using namespace std;
 4
 5 //subsequence的本质是多个array相连,所以我们从后往前找array就可以了
 6 int a[1005];
 7 long long dp[1005],c[1005][1005];//dp[i]代表从i-n,从i开始的subsequence个数
 8 long long ans;
 9 int mod = 998244353;
10
11 int main(){
12     int n; cin>>n;
13     for(int i=1;i<=n;i++) cin>>a[i];
14
15     for(int i=1;i<=1000;i++){
16         for(int j=1;j<=1000;j++){
17             if(j==1) c[i][j]=i;
18             else c[i][j] = (c[i-1][j]+c[i-1][j-1])%mod;
19
20         }
21     }
22
23     dp[n+1]=1;
24
25     for(int i=n-1;i>=1;i--){
26         if( a[i]<=0 || a[i]+i>n ) continue;
27         for(int j=i+a[i]+1;j<=n+1;j++){//array后面加good sequence还是good sequence ==> 枚举good sequence可以加的位置
28             dp[i] +=  c[ j-i-1 ][ a[i] ] * dp[j] ;
29             dp[i] %= mod;
30         }
31     }
32
33     int sum = 0;
34     for(int i = 0; i < n; ++i){
35         sum += dp[i];
36         sum %= mod;
37     }
38     cout << sum << endl;
39
40     return 0;
41 }

转载于:https://www.cnblogs.com/ZhenghangHu/p/9248598.html

Codeforces 1000D Yet Another Problem On a Subsequence 【dp】【组合数学】相关推荐

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

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

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

  3. Codeforces 1000D Yet Another Problem On a Subsequence

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

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

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

  5. CodeForces - 336D Vasily the Bear and Beautiful Strings(dp+组合数学)

    题目链接:点击查看 题目大意:给出一个 01 字符串,规定求值的过程如下: 每次选择末尾的两个数字: 如果为 0 0 ,那么替换成一个 1 否则替换成一个 0 循环往复,直至只剩一个数字位置,剩下的数 ...

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

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

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

  8. 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 mega ...

  9. Codeforces 776D The Door Problem

    题目链接:http://codeforces.com/contest/776/problem/D 把每一个钥匙拆成两个点${x,x+m}$,分别表示选不选这把钥匙. 我们知道一扇门一定对应了两把钥匙. ...

最新文章

  1. php中的单引号与双引号详解
  2. [转]前端构建工具gulpjs的使用介绍及技巧
  3. lib和dll的区别
  4. 容器搭建Hadoop步骤
  5. jdk的selector(2)channel的注册
  6. LeetCode1.两数之和
  7. 清华大学python视频_涨见识了,清华大学全套Python642集视频教程泄露,拿走玩去...
  8. SQL 语句 - Select(2): 指定表中的字段
  9. 在容器服务kubernetes上配置https
  10. windows L2TP 拨号无法连接
  11. java使用memcached
  12. 摇滚bono_摇滚,Paper弹枪对尼古拉斯·弗朗西斯的采访
  13. 4484: [Jsoi2015]最小表示(拓扑序+bitset维护连通性)
  14. The King’s Ups and Downs HDU - 4489(计数+dp)
  15. 数字手写识别——Java实现KNN算法
  16. Excel VBA编程常用语句300句
  17. 六款在线项目管理工具
  18. 【操作系统】“哲学家进餐”问题
  19. 软件测试 | 测试开发 | 时间管理之四象限法则
  20. java敏感词过滤器组件

热门文章

  1. 上墙抽奖php代码,年会微信大屏上墙抽奖系统PHP独立后台版源码
  2. 前端必备 PS三种切图方法 Cutterman最好用的切图工具
  3. 解析底层原理!阿里P7级别面试经验总结,2年以上经验必看
  4. Oracle数据库官方权威内部培训教材
  5. 初中计算机应用教什么,《初中信息技术课程中为什么要学习excel》
  6. MessageBox ShowNumber 之类的迷案
  7. #BDA#笔记#阶段一:制作数据分析报告
  8. ubuntu同时使用有线和无线
  9. PMP之假设日志Assumption Log
  10. php字符串操作整理,PHP 字符串操作整理