hdu 4055 Number String
2013-10-04 10:13
302 查看
题意:给出一个字符串,问1~n这n个数中有多少种排列满足给定字符串的要求,字符串str[i]=='I'代表第i位数字要比它前一位大,str[i]=='D'代表第i位数字要比它前一位小,str[i]=='?'代表第i位数字任意。
思路:刚开始没想出怎么做,看了看题解,感觉大体思路还是能看懂的,但是细节的地方怎么也没看明白,我理解能力是有多差Orz……后来没办法了,自己YY过了,果然还是自己想的思路好写。我的思路是这样的:在1~n中拿走任意一个数,剩下的数其实可以重新编号(1~n-1),所以每一次选的时候也可以看成是一个1~k(k是当前剩下的数)的数选一个。这样的话,第i次选的数就取决于第i-1次选的数在它剩下的数中的位置了。用dp[i][j]表示到第i位时,在剩下的数中选第j个数的排列的个数。这样的话状态转移方程很容易就能列出来:如果str[i]=='I',dp[i][j]=sum{dp[i-1][1]~dp[i-1][j]},如果str[i]=='D',dp[i][j]=sum{dp[i-1][j+1]~dp[i-1][k]}(k是到i-1位时剩余的数)。这题数组开long
long 的话居然会超时,这数据……不能多说。
代码:
思路:刚开始没想出怎么做,看了看题解,感觉大体思路还是能看懂的,但是细节的地方怎么也没看明白,我理解能力是有多差Orz……后来没办法了,自己YY过了,果然还是自己想的思路好写。我的思路是这样的:在1~n中拿走任意一个数,剩下的数其实可以重新编号(1~n-1),所以每一次选的时候也可以看成是一个1~k(k是当前剩下的数)的数选一个。这样的话,第i次选的数就取决于第i-1次选的数在它剩下的数中的位置了。用dp[i][j]表示到第i位时,在剩下的数中选第j个数的排列的个数。这样的话状态转移方程很容易就能列出来:如果str[i]=='I',dp[i][j]=sum{dp[i-1][1]~dp[i-1][j]},如果str[i]=='D',dp[i][j]=sum{dp[i-1][j+1]~dp[i-1][k]}(k是到i-1位时剩余的数)。这题数组开long
long 的话居然会超时,这数据……不能多说。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<cmath> #include<vector> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; const int maxn=1000+10; const int mod=1000000007; char str[maxn]; int dp[maxn][maxn],sum[maxn][maxn]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n; while(~scanf("%s",str)) { n=strlen(str); n++; memset(dp,0,sizeof(dp)); for(int i=1;i<=n;++i) sum[i][0]=0; for(int i=1;i<=n;++i) { dp[1][i]=1; sum[1][i]=i; } for(int i=2;i<=n;++i) { for(int j=1;j<=n-i+1;++j) { if(str[i-2]=='I'||str[i-2]=='?') dp[i][j]+=sum[i-1][j]-sum[i-1][0]; if(str[i-2]=='D'||str[i-2]=='?') dp[i][j]+=sum[i-1][n-i+2]-sum[i-1][j]; dp[i][j]%=mod; sum[i][j]=(sum[i][j-1]+dp[i][j])%mod; } } int res=(dp [1]+mod)%mod; printf("%d\n",res); } return 0; }
相关文章推荐
- [poj 1699]Best Sequence[kmp][DP]
- 两道面试题
- 几种进程间的通信方式
- Spring error at ::0 can't find referenced pointcut myMethod等异常的解决
- linux系统日志使用
- hdu4764 and hdu1846 and poj1067(威佐夫博奕,min博弈)
- C#多线程操作界面控件的解决方案
- 汇编寄存器的使用,SI,DI的使用
- ZOJ 2624 Popo's Lamps(DP 记忆化搜索)
- Windows2012R2之虚拟机自动激活
- 解决类重定义错误
- 异步处理并不能减少单次请求的响应时间
- 斗地主出牌规则
- SPOJ3713——Primitive Root
- 四元数旋转向量
- Entity Framework Code First数据库连接
- Apache和IIS共享80端口的四个设置方法
- My Emacs For Common Lisp
- 【读书笔记】 spinlock, mutex and rwlock 的性能比较
- 软件设计师大纲:软件设计考试科目综合分析