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. excel导出功能原型

    本篇博客是记录自己实现的excel导出功能原型,下面我将简单介绍本原型: 这是我自制的窗体,有一个ListView和一个Button(导出)控件. 这是我在网上找到了使用exel需要引用的库. usi ...

  2. C#高级编程 (第六版) 学习 第六章:运算符和类型强制转换

    第六章 运算符和类型强制转换 1,运算符 类别 运算符 算术运算符 + - * / % 逻辑运算符 & | ^ ~ && || ! 字符串连接运算符 + 增量和减量运算符 ++ ...

  3. YARN中用的作业调度算法:DRF(Dominant Resource Fairness)

    在Mesos和YARN中,都用到了dominant resource fairness算法(DRF),它不同于hadoop基于slot-based实现的fair scheduler和capacity ...

  4. CodeForces Round #527 (Div3) B. Teams Forming

    http://codeforces.com/contest/1092/problem/B There are nn students in a university. The number of st ...

  5. openssl 编程

    背景: 生成私钥.公钥 --> 生成AES-key seed[32], iv[16] --> 公钥加密ASE-key, IV,传给Server --> Server用私钥解密,得到A ...

  6. fsocket发送post实现异步请求

    function triggerRequest($url, $post_data = array(), $cookie = array()){ //可以通过POST或者GET传递一些参数给要触发的脚本 ...

  7. PHP中面向对象编程思想的3个特征

    面向对象编程思想的3个特征: 封装: 无非是一个大的指向思想,目的是为了将一个类设计得更为健壮! 其基本做法是: 尽可能地将一个类的成员私有化,只开放那些必不可少的对外的属性或方法,能private的 ...

  8. python的N个小功能(找到符合要求的图片,重命名,改格式,缩放,进行随机分配)

    ########################################################################## 循环读取该目录下所有子目录和子文件 ####### ...

  9. 【bzoj1495】[NOI2006]网络收费 暴力+树形背包dp

    题目描述 给出一个有 $2^n$ 个叶子节点的完全二叉树.每个叶子节点可以选择黑白两种颜色. 对于每个非叶子节点左子树中的叶子节点 $i$ 和右子树中的叶子节点 $j$ :如果 $i$ 和 $j$ 的 ...

  10. 详解SQL Server数据修复命令DBCC的使用

    严重级别为 21 表示可能存在数据损坏. 可能的原因包括损坏的页链.损坏的 IAM 或该对象的 sys.objects目录视图中存在无效条目. 这些错误通常由硬件或磁盘设备驱动程序故障而引起. MS ...