Number String

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1016    Accepted Submission(s): 440

Problem Description
The signature of a permutation is a string that is computed as follows: for each pair of consecutive elements of the permutation, write down the letter 'I' (increasing) if the second element is greater than the first one, otherwise write down the letter 'D' (decreasing). For example, the signature of the permutation {3,1,2,7,4,6,5} is "DIIDID".

Your task is as follows: You are given a string describing the signature of many possible permutations, find out how many permutations satisfy this signature.

Note: For any positive integer n, a permutation of n elements is a sequence of length n that contains each of the integers 1 through n exactly once.

 
Input
Each test case consists of a string of 1 to 1000 characters long, containing only the letters 'I', 'D' or '?', representing a permutation signature.

Each test case occupies exactly one single line, without leading or trailing spaces.

Proceed to the end of file. The '?' in these strings can be either 'I' or 'D'.

 
Output
For each test case, print the number of permutations satisfying the signature on a single line. In case the result is too large, print the remainder modulo 1000000007.

 
Sample Input
II
ID
DI
DD
?D
??
 
Sample Output
1
2
2
1
3
6

Hint

Permutation {1,2,3} has signature "II".
Permutations {1,3,2} and {2,3,1} have signature "ID".
Permutations {3,1,2} and {2,1,3} have signature "DI".
Permutation {3,2,1} has signature "DD".
"?D" can be either "ID" or "DD".
"??" gives all possible permutations of length 3.

 
Author
HONG, Qize
 
Source
 
Recommend
lcy
 
题意:
由数字1到n组成的所有排列中,问满足题目所给的n-1个字符的排列有多少个,如果第i字符是‘I’表示排列中的第i-1个数是小于第i个数的。如果是‘D’,则反之。
思路:
首先考虑子问题。设所给模式串长度为i。我们考虑前i-1匹配结尾为j的方法数和长度为i以k结尾的方法数。
我们设dp[i][j]表示前i个位置匹配(即满足条件)且以j结尾的方法数。那么有一个规律。如果前i个位置匹配。对于任意
1<=m<=i。其中x€[m,i]加1后仍匹配。因为大的增幅一致依然大。小的还是小。不过怎么得到递推方程呢?
我们要求dp[i][j]。
1.如果模式串第i位为'I'那么dp[i][j]=segma(dp[i-1][k]).k<j。因为dp[i-1][k]的组合中大于等于j的位置仍满足匹配。而k<j所以可以成功转移。
2.如果模式串第i位为'D'那么dp[i][j]=segma(dp[i-1][k]).k>=j。因为dp[i-1][k]的组合中大于等于j的位置仍满足匹配。而k>=加1后大于j所以可以成功转移。
不过如何保证状态全是dp[i-1]转移来的呢。其实dp[i][j]只是在dp[i-1][k]的基础上增加了一个数i。而把j这个数放到了最后一位而已。而我们用i这个数替换掉j这个数。前面还剩i-1个数。所以dp[i]的状态一定是从dp[i-1]对x€[m,i]加1后转移得到。本来转移有三层循环的不过可以有前缀和优化。用空间换时间了。
详细见代码:
#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxn=1010;
const int mod=1000000007;
char st[maxn];
int dp[2][maxn],sum[2][maxn]; int main()
{
int i,j,len,v,u; sum[1][0]=sum[0][0]=0;
while(~scanf("%s",st+2))
{
v=0;
len=strlen(st+2);
dp[0][1]=sum[0][1]=1;
for(i=2;i<=len+1;i++)//第一个数前没有数所以从2开始。一直到len+1
{
u=v^1;
for(j=1;j<=i;j++)
{
if(st[i]=='I')
dp[u][j]=sum[v][j-1];
else if(st[i]=='D')
dp[u][j]=(sum[v][i-1]-sum[v][j-1]+mod)%mod;//由于取模可能使大的变小
else
dp[u][j]=sum[v][i-1];
sum[u][j]=(dp[u][j]+sum[u][j-1])%mod;
//printf("sum[%d][%d]:%d\n",i,j,sum[v^1][j]);
}
v=u;
}
printf("%d\n",sum[v][len+1]);
}
return 0;
}

感想:
想了大半个晚上。终于想通点了。DP做着还不是那么顺手。还是题做少了啊。不过我不会放弃的。坚持一定会有效果。加油!


hdu 4055 Number String(有点思维的DP)的更多相关文章

  1. HDU 4055 Number String dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4055 Number String Time Limit: 10000/5000 MS (Java/O ...

  2. hdu 4055 Number String (基础dp)

    Number String Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. hdu 4055 Number String

    Number String http://acm.hdu.edu.cn/showproblem.php?pid=4055 Time Limit: 10000/5000 MS (Java/Others) ...

  4. HDU 4055 Number String:前缀和优化dp【增长趋势——处理重复选数】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4055 题意: 给你一个由'I', 'D', '?'组成的字符串,长度为n,代表了一个1~n+1的排列中 ...

  5. hdu 4055 Number String(dp)

    Problem Description The signature of a permutation is a string that is computed as follows: for each ...

  6. HDU 4055 Number String (计数DP)

    题意:由数字1到n组成的所有排列中,问满足题目所给的n-1个字符的排列有多少个,如果第i字符是‘I’表示排列中的第i-1个数是小于第i个数的. 如果是‘D’,则反之. 析:dp[i][j] 表示前 i ...

  7. HDU 4055 Number String(DP计数)

    题意: 给你一个含n个字符的字符串,字符为'D'时表示小于号,字符为“I”时表示大于号,字符为“?”时表示大小于都可以.比如排列 {3, 1, 2, 7, 4, 6, 5} 表示为字符串 DIIDID ...

  8. hdu 4055 Number String(递推DP)

    给一个只含‘I','D','?'三种字符的字符串,I表示当前数字大于前面的数字,D表示当前的数字小于前面一位的数字,?表示当前位既可以小于又可以大于. 问1~n的排列中有多少个满足该字符串. http ...

  9. HDU 4054 Number String

    HDU 4054 Number String 思路: 状态:dp[i][j]表示以j结尾i的排列 状态转移: 如果s[i - 1]是' I ',那么dp[i][j] = dp[i-1][j-1] + ...

随机推荐

  1. Python获取当地的天气和随意城市的天气

    先从中国天气网得到数据('http://www.weather.com.cn/data/cityinfo/'+城市编码),每一个城市都有各自的编码,怎样得到用户所在地的城市编码呢?用一个网页就是专门干 ...

  2. 01-UIKit

    目录: 一.视图和控制器 二.interface Builder 回到顶部 一.视图和控制器 1 视图(view)ios程序运行期间用户所能看见的东西都可以认为是视图,比如UIwindow就是一个视图 ...

  3. JMS开源比较

    Java开源JMS消息中间件 mom4j mom4j是一个完全实现JMS1.1规范的消息中间件并且向下兼容JMS1.0与1.02.它提供了自己的消息处理存储使它独立于关系数据与语言,所以它的客户端可以 ...

  4. powerMock比easyMock和Mockito更强大(转)

    powerMock是基于easyMock或Mockito扩展出来的增强版本,所以powerMock分两种类型,如果你习惯于使用easyMock的,那你就下载基于easyMock的powerMock,反 ...

  5. 扩展 Windows Azure 运营能力 – 巴西

    今天早些时候,在巴西圣保罗的一个活动上,我宣布了我们将在巴西设立一个 Windows Azure 区域数据中心的计划.我们希望该区域中心可以在 2014 年年初上线,并且我们很高兴地宣布将在未来 4 ...

  6. 基于visual Studio2013解决C语言竞赛题之0707月份输出

     题目 解决代码及点评 /* 编一程序,打入月份号,输出该月的英文月名. 例如,输入"3",则输出"March",要求用指针数组处理. */ #includ ...

  7. C++ map排序(按照value值排序)_glp_hit_新浪博客

    C++ map排序(按照value值排序)_glp_hit_新浪博客     C++ map排序(按照value值排序)    (2012-07-12 14:19:51)    转载▼    标签:  ...

  8. jQuery操作checkbox的问题

    问题: 使用 jquery 的 attr('checked',false) 和 attr('checked',true) 方法给 checkbox 设置选中和未选中状态时,失效. 原因: jquery ...

  9. PHP - 接口 - 单一接口

    /* * 接口的使用 */ //定义接口 interface IPerosn{ public function eat(); public function water(); } //定义继承自接口的 ...

  10. jQuery.mobile.changePage() | jQuery Mobile API Documentation

    jQuery.mobile.changePage() | jQuery Mobile API Documentation <script> $.mobile.changePage( &qu ...