题意:

给出一个由I、D和?组成的串,串的长度是n,我们要根据串的规则构造出满足的由1~n+1组成的数列,其中每个数字只出现一次。串的规则定义如下:

如果当前字母是I,我们要保证这一位的数字要比前一位大,如果是D,则比前一位小,?代表都可以。请求出满足串的规则的数列的个数。

思路:

首先我们构造状态如下:

dp[i][j]=k 表示我们用1~i这些数字构造前i位且第i位是j的情况数目是k。

同时定义:sum[i][j]=dp[i][1]+dp[i][2]+...+dp[i][j];

很容易想到:如果当前位是I,dp[i][j]=sum[i-1][j-1];

如果当前位是D呢?我们如果用朴素的想法:dp[i][j]=sum[i-1][n]-sum[i-1][j-1],这样可能会数字填重复,所以我们要换个思路。

很容易想到,如果一个数列是{1,2,3},如果我们要在末尾插入一个2,数列就会变的不合法,但是如果我们把{1,2,3}中的大于2的数字都加1,这样数列就变成了{1,3,4},我们插入2就合法了,所以当当前位是D的时候,我们想到了下面的转移方程:

dp[i][j]=sum[i-1][i-1]-sum[i-1][j-1];

处理?的时候就两个都跑一遍,同时要注意同余模,减法的同余模:

(a-b)%mod=(a%mod-b%mod+mod)%mod

因为这个我们还WA了一次。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;const long long maxn = 1005;
const long long mod =  1000000007;long long dp[maxn][maxn];
char str[maxn];
long long sum[maxn];int main() {while(EOF != scanf("%s",str)) {memset(dp, 0, sizeof(dp));memset(sum, 0, sizeof(sum));sum[1] = 1;dp[1][1] = 1;long long l = strlen(str);long long ans = 0;for(long long i = 2; i <= l + 1; i ++) {if(str[i - 2] == 'I') {for(long long j = 1; j <= i; j++) {dp[i][j] += sum[j - 1];dp[i][j] %= mod;}} else if(str[i - 2] == 'D') {for(long long j = 1; j <= i; j++) {long long tmp = (sum[i - 1] - sum[j - 1] + mod) % mod;dp[i][j] += tmp;dp[i][j] %= mod;}} else {for(long long j = 1; j <= i; j++) {dp[i][j] += sum[j - 1];dp[i][j] %= mod;}for(long long j = 1; j <= i; j++) {long long tmp = (sum[i - 1] - sum[j - 1] + mod) % mod;dp[i][j] += tmp;dp[i][j] %= mod;}}sum[0] = 0;for(long long j = 1; j <= i; j++) {sum[j] = sum[j - 1] + dp[i][j];sum[j] %= mod;}}    printf("%lld\n", sum[l + 1]);}return 0;
}

uvali5697(DP)相关推荐

  1. dp,sp,px相互转化

    方法一: public int sp2px(float sp) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, ...

  2. [JS][dp]题解 | #打家劫舍(一)#

    题解 | #打家劫舍(一)# 题目链接 打家劫舍(一) 题目描述 描述 你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家, ...

  3. HDU 2084 数塔(DP)(JAVA版)

    数塔 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  4. dp cf 20190615

    A. Timofey and a tree 这个不算是dp,就是一个思维题,好难想的思维题,看了题解才写出来的, 把点和边分开,如果一条边的两个点颜色不同就是特殊边,特殊边两边连的点就叫特殊点, 如果 ...

  5. BZOJ 1003[ZJOI2006]物流运输(SPFA+DP)

    Problem 1003. -- [ZJOI2006]物流运输 1003: [ZJOI2006]物流运输 Time Limit: 10 Sec  Memory Limit: 162 MB Submit ...

  6. [NOI2005]聪聪与可可(期望dp)

    题意:给一张无向图,有一只猫和一只老鼠,猫每秒会向老鼠的方向移动两个单位,若它们的距离为一,那么只会移动一个单位,老鼠会等概率向周围移动一步或不动,求猫抓到老鼠的期望时间. Solution luog ...

  7. Codeforces 903F Clear The Matrix(状态压缩DP)

    题目链接 Clear The Matrix 题意 给定一个$4 * n$的矩形,里面的元素为$'.'$或$'*'$.现在有$4$种正方形可以覆盖掉$'*'$,正方形的边长分别为$1,2,3,4$. 求 ...

  8. 喵哈哈村的魔法考试 Round #1 (Div.2) 题解源码(A.水+暴力,B.dp+栈)

    A.喵哈哈村的魔法石 发布时间: 2017年2月21日 20:05   最后更新: 2017年2月21日 20:06   时间限制: 1000ms   内存限制: 128M 描述 传说喵哈哈村有三种神 ...

  9. 尼克的任务 dp 洛谷1280

    蒟蒻表示老久没看过dp题目了,,挺水的一道dp题目都没想出来,,, 首先设dp[i]表示从开始到i时间的最大空闲时间,用vector to[x] 表示从x点开始的任务结束时间,cnt[x]表示从x开始 ...

最新文章

  1. 常见的http状态码(Http Status Code)
  2. c语言影碟出租程序设计总结,vc++影碟出租系统的设计与开发
  3. 使用MySQL的23个注意事项
  4. 【原创】多dpi适配的新姿势
  5. hdi-shared Service plan的分配
  6. 权限管理系统系列之序言
  7. dspmq dspmqver command not found(dspmq命令找不到,dspmqver主安装目录设置不正确
  8. 机器学习算法之生成树
  9. 数据科学和人工智能技术笔记 十二、逻辑回归
  10. java快速注释怎么配置_详解如何在低版本的Spring中快速实现类似自动配置的功能...
  11. django model filter_2020年最新Django经典面试问题与答案汇总(上)大江狗整理
  12. 单源最短路径的Bellman-Ford算法。
  13. 4月1日起支付宝、微信扫码支付单日限额500元,够用吗?
  14. 本科生计算机核心期刊论文,计算机本科生学位论文参考文献 计算机本科生核心期刊参考文献哪里找...
  15. 【java支付一 】java整合银联支付
  16. LODOP打印控件使用问题总结
  17. python ---- 图像小波变换DWT
  18. 使用Packer在Winodws VMware Workstation Pro上自动部署Windows Server 2016中文版
  19. 健身管理系统 -健身管理软件模板
  20. 第2章-系统控制原理 -> 线性系统理论

热门文章

  1. 第16课:项目实战——利用 PyTorch 构建 CNN 模型
  2. 撒花!吴恩达《Machine Learning Yearning》完结!
  3. Redis介绍及常用应用场景介绍
  4. Qt入门——三个臭皮匠顶个诸葛亮
  5. WCF4中舍去svc文件
  6. GPS服务端解析程序编写日记之--vs2010中多种语言开发及调试的若干注意事项
  7. 动态加载JS脚本的4种方法
  8. python常见可视化图像及实现代码
  9. Oracle 根据字符串的长度排序
  10. 双向循环链表的冒泡排序