DP


Description

对于一个排列,考虑相邻的两个元素,如果后面一个比前面一个大,表示这个位置是上升的,用 I 表示,反之这个位置是下降的,用 D表示。如排列 3,1,2,7,4,6,5 可以表示为 DIIDID。 现在给出一个长度为 n-1的排列表示,问有多少种 1 到n 的排列满足这种表示。

Input

一个字符串 S,S 由 I,D,?组成。?表示这个位置既可以为 I,又可以为 D

对于 20%的数据,S 长度 ≤ 10;

对于 100%的数据,S长度 ≤ 1000。

Output

有多少种排列满足上述字符串。输出排列数模 1000000007。

Sample Input

?D

Sample Output

3


这是一道比较裸的动态规划题目,dp[i][j]表示前 i 位数中,最后一位为第 j 大的方案数。即当转移到i时,前 i - 1 位数是1 ~ i-1 中的数。此时:

  1. 如果输入为 I,那么 j 可由 1 ~ j-1 转移过来,大于等于 j 的数都加一即可保证前 i 个数为1 ~ i;
  2. 如果输入为 D,则 j 可由 j ~ i-1 转移而来,同样,大于等于 j 的数字都加一。
  3. 如果输入为 ?,则将前两种方案加起来。

在实际转移过程中,不用涉及到大于等于 j 的数加一,只需知道转移原理即可。

但是如果直接这样转移当然是不行的,还需注意到,题目中 \(n <= 10^3\),

转移是\(n^3\),会超时。所以我们可以在转移之前维护一个前缀和即可去掉一个\(n\)。使时间复杂度降为\(n^2\)。如果害怕爆空间,还可以采用滚动数组进行优化。

Ps: 本题还有一个点需要注意,由于前缀和取了模,在算下降情况时,可能会出现负数,所以先加上一个mod再取模。

至此,问题完美解决。

代码

#include <cstdio>

int dp[2][1005];
const int mod = 1000000007; int main() {
dp[0][1] = 1;
int cur = 0;
char x = getchar();
int i = 1;
while(x == 'I'||x == 'D'||x == '?') {
cur ^= 1;i++;
for(int j = 1;j < i;j++)dp[cur^1][j] += dp[cur^1][j-1],dp[cur^1][j] %= mod,dp[cur][j] = 0; if(x == 'I') {
for(int j = 2;j <= i;j++)dp[cur][j] = dp[cur^1][j-1],dp[cur][j] %= mod;
}
if(x == 'D') {
for(int j = 1;j < i;j++)dp[cur][j] = dp[cur^1][i-1] - dp[cur^1][j-1] + mod,dp[cur][j] %= mod;
}
if(x == '?') {
for(int j = 2;j <= i;j++)dp[cur][j] = dp[cur^1][j-1],dp[cur][j] %= mod;
for(int j = 1;j < i;j++)dp[cur][j] += dp[cur^1][i-1] - dp[cur^1][j-1] + mod,dp[cur][j] %= mod;
}
x = getchar();
}
int ans = 0;
for(int j = 1;j <= i;j++)ans = (ans + dp[cur][j]) % mod;
printf("%d",ans); return 0;
}

最新文章

  1. getContentResolver()内容解析者查询联系人、插入联系人
  2. Android线程池(二)
  3. 论文阅读之 Inferring Analogous Attributes CVPR 2014
  4. 单点登录系统构建之二——SSO原理及CAS架构
  5. Redis 安全
  6. hdu 4267 树形DP
  7. linux Page cache和buffer cache----- systemtap
  8. Ext.Net学习笔记12:Ext.Net GridPanel Filter用法
  9. Book of Evil
  10. Linxu安装Lamp环境
  11. 程序员之---C语言细节22(函数返回指针注意事项&amp;lt;悬空指针&amp;gt;、查看进程能够分配的内存大小)
  12. 【hoj】2651 pie 二分查找
  13. spring boot 登录注册 demo (二) -- 数据库访问
  14. The 16th tip of DB Query Analyzer
  15. Linux基本命令总结(九)
  16. vue框架与koa2服务器实现跨域通信
  17. Notepad++远程连接Linux系统
  18. idea使用docker-maven-plugin插件将项目编译为docker镜像到远程linux服务器 原
  19. #if _MSC_VER &amp;gt; 1000 #pragma once #endif 含义
  20. stylus项目知识点

热门文章

  1. js 闭包的简单理解
  2. IOS第18天(7,CAKeyframeAnimation-图标抖动)
  3. php中htmlspecialchars和htmlentiti
  4. Cocos2dx淌坑日记:粒子系统PositionType的正确使用
  5. spring和mybatis集成,自动生成model、mapper,增加mybatis分页功能
  6. 【Algorithms】归并排序(merge sort)
  7. robots
  8. Windows上搭建Kafka运行环境
  9. IOS asc码替换
  10. Struts2(六):ResultType