Number String

http://acm.hdu.edu.cn/showproblem.php?pid=4055

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

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.
 
 
题意:
给出长为n的一个字符串,根据这个字符串构造长为n+1的数字串
字符为‘I’,下一个数字要比这一个数字大
字符为‘D’ ,下一个数字要比这一个数字小
字符为‘?’,下一个数字没有限制
问数字串有多少种方案
 
一般套路:
f[i][j]表示长为i的串中,最后一个数字为j的方案数
若字符为‘I’,f[i][j]= Σ f[i-1][x]   1 <= x < j     
若字符为‘D’,f[i][j]= Σ f[i-1][x]  j <= x <= i-1  
若字符为‘?’,f[i][j]=Σ f[i-1][x]  1 <= x <= i-1
我们虽然根据 字符保证了相邻两个数字的大小关系,但并没有保证数字串里前i-1个数字没有数字j
这就有了后效性。怎么办?
给状态增加含义:必须选前i-1个数字
我们将过程想象为一个一个填数字的过程
那么由f[i-1][]向f[i][]的转移,就是在末尾(i位置)填上数字i
(因为状态的定义是必须选前i-1个数字)
那么岂不是只能填数字i?字符为‘D’时不就错了吗?第二维不就没有用吗?
我们考虑第二维j(要填的最后一个数字),
我们是否可以将填数字i转换到填数字j,
那么状态转移的时候,就要想如何填j使相邻数字的大小关系不变
将前i-1个数字>=j的都+1,这样就拿出了j,放在最后面
所以,上方状态转移成立
时间复杂度?O(n³) TLE
 
前缀和优化,时间复杂度O(n²)
其实很简单,照着原方程x的取值范围写就行
 1 <= x < j     前缀和就是sum[i-1][j-1]
j <= x <= i-1  前缀和就是 sum[i-1][i-1]-sum[i-1][j-1]
 1 <= x <= i-1  前缀和就是sum[i-1][i-1]
前缀和的更新: sum[i][j]=(sum[i][j-1]+f[i][j])%mod;
 
前缀和优化代码
#include<cstdio>
#include<cstring>
#define mod 1000000007
using namespace std;
int len,f[][],sum[][];
char s[];
int main()
{
while(scanf("%s",s+)!=EOF)
{
memset(f,,sizeof(f));
len=strlen(s+);
f[][]=; sum[][]=;
for(int i=;i<=len+;i++)
for(int j=;j<=i;j++)
{
if(s[i-]=='I') f[i][j]=sum[i-][j-];
else if(s[i-]=='D') f[i][j]=((sum[i-][i-]-sum[i-][j-])%mod+mod)%mod;
else f[i][j]=sum[i-][i-];
sum[i][j]=(sum[i][j-]+f[i][j])%mod;
}
printf("%d\n",sum[len+][len+]);
}
}

未优化代码

#include<cstdio>
#include<cstring>
#define mod 1000000007
using namespace std;
int len,f[][];
char s[];
int main()
{
while(scanf("%s",s+)!=EOF)
{
memset(f,,sizeof(f));
len=strlen(s+);
f[][]=;
for(int i=;i<=len+;i++)
for(int j=;j<=i;j++)
{
if(s[i-]=='I')
for(int k=;k<j;k++) f[i][j]+=f[i-][k];
else if(s[i-]=='D')
for(int k=j;k<i;k++) f[i][j]+=f[i-][k];
else
for(int k=;k<i;k++) f[i][j]+=f[i-][k];
}
int ans=;
for(int i=;i<=len+;i++) ans+=f[len+][i];
printf("%d\n",ans);
}
}

hdu 4055 Number String的更多相关文章

  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) T ...

  3. hdu 4055 Number String (基础dp)

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

  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. Scrum立会报告+燃尽图(十一月二十日总第二十八次):功能开发与纪录版本控制报告

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...

  2. 阿帕奇web服务器下载部署安装运行

    链接: https://jingyan.baidu.com/album/d8072ac47baf0eec95cefdca.html?picindex=4 1.apache服务安装成功可是启动失败“wi ...

  3. 如何防止app接口被别人调用

    app开发的时候,如何保护app的接口呢? 用https是我想到的办法,但是不知道怎么实现,所以就考虑用token,虽然不是绝对有效,但是能防止一般的用户来攻击,高手非要攻击,只能报警了吧. toke ...

  4. nodepad++ 格式化xml插件

    1.用插件管理器安装xmltools插件 2.使用如下菜单格式化xml: 所有插件下载地址: http://sourceforge.net/projects/npp-plugins/files/

  5. Scrum 项目准备3.0

    SCRUM 流程的步骤2: Spring 计划 1. 确保product backlog井然有序.(参考示例图1) 2. Sprint周期,一个冲刺周期,长度定为两周,本学期还有三个冲刺周期. Spr ...

  6. PC和FPGA间的串口通信实现

    应用笔记 V1.0 2015/03/26 PC和FPGA间的串口通信实现   概述   本文将介绍PC和FPGA间的串口通信实现的基本思路和Verilog代码,对于通信而言,收发双方都要有相应的控制. ...

  7. 第194天:js---函数对象详解(arguments、length)

    一.函数即对象 function add1(a,b){ return a+b; } //Function对象的实例 -- 高级技巧 --- 写框架必须用的... //前面表示参数,后面表示函数语句 v ...

  8. 第124天:移动web端-Bootstrap轮播图插件使用

    Bootstrap JS插件使用 > 对于Bootstrap的JS插件,我们只需要将文档实例中的代码粘到我们自己的代码中> 然后作出相应的样式调整 Bootstrap中轮播图插件叫作Car ...

  9. HDU2486_A simple stone game

    这个题目是这样的,一堆石子有n个,首先第一个人开始可以去1-(n-1)个,接下来两人轮流取石子,每个人可取的石子数必须是一个不超过上一次被取的石子的K倍的整数. 现在求对于一堆数量为n的石子是否为必胜 ...

  10. 【bzoj2121】字符串游戏 区间dp

    题目描述 给你一个字符串L和一个字符串集合S,如果S的某个子串在S集合中,那么可以将其删去,剩余的部分拼到一起成为新的L串.问:最后剩下的串长度的最小值. 输入 输入的第一行包含一个字符串,表示L. ...