zoj 3543 - Number String(动规)

2023-11-20 19:08
文章标签 string number zoj 动规 3543

本文主要是介绍zoj 3543 - Number String(动规),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

摘:http://blog.csdn.net/morgan_xww/article/details/6847305

为什么能够能从子问题转移?

  在做dp[i][j]转移我们可以在前一状态中将超过j的值的数+1,就像从1,4,3,2 加3的时候 变成1,5,4,2,3(增减性不变)

状态:dp[i][j] 表示长度为i以j结尾的合法的排列个数(由1...i组成的排列)。

状态转移:if(s[i]=='I') dp[i][j] = dp[i-1][1] + dp[i-1][2] + ... + dp[i-1][j-1];
        if(s[i]=='D') dp[i][j] = dp[i-1][j+1] +...+ dp[i-1][i-1]+dp[i-1][i](这里等于dp[i][j],原理见附加结论);
        if(s[i]=='?') dp[i][j] = dp[i-1][1] + dp[i-1][2] + ... + dp[i-1][i-1];
还要清楚一个结论:
给定一个长度为i-1的字符串,由{1,2,...,i}组成的合法排列数和由{1,2,...,j-1,j+1,...,i+1}
组成的合法排列数是相同的。


时间复杂度是O(n^3)的,但定义一个sum[i][j]利用部分求和,就转化成了O(n^2).

代码如下:

int main()
{while(~scanf("%s", s)){int len = strlen(s)+1;dp[1][1] = sum[1][1] = 1;for(int i = 2; i <= len; ++i)for(int j = 1; j <= i; ++j){if(s[i-2]=='D') dp[i][j] = (sum[i-1][i-1]-sum[i-1][j-1]+mod)%mod;else if(s[i-2]=='I') dp[i][j] = sum[i-1][j-1];else if(s[i-2]=='?') dp[i][j] = sum[i-1][i-1];sum[i][j] = (sum[i][j-1]+dp[i][j])%mod;}printf("%lld\n", sum[len][len]);}return 0;
}


这篇关于zoj 3543 - Number String(动规)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/396788

相关文章

usaco 1.2 Name That Number(数字字母转化)

巧妙的利用code[b[0]-'A'] 将字符ABC...Z转换为数字 需要注意的是重新开一个数组 c [ ] 存储字符串 应人为的在末尾附上 ‘ \ 0 ’ 详见代码: /*ID: who jayLANG: C++TASK: namenum*/#include<stdio.h>#include<string.h>int main(){FILE *fin = fopen (

数论ZOJ 2562

题意:给定一个数N,求小于等于N的所有数当中,约数最多的一个数,如果存在多个这样的数,输出其中最大的一个。 分析:反素数定义:对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数。 性质一:一个反素数的质因子必然是从2开始连续的质数。 性质二:p=2^t1*3^t2*5^t3*7

zoj 1721 判断2条线段(完全)相交

给出起点,终点,与一些障碍线段。 求起点到终点的最短路。 枚举2点的距离,然后最短路。 2点可达条件:没有线段与这2点所构成的线段(完全)相交。 const double eps = 1e-8 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;

zoj 4624

题目分析:有两排灯,每排n个,每个灯亮的概率为p,每个灯之间互不影响,亮了的灯不再灭,问两排中,每排有大于等于m个灯亮的概率。 设dp[ i ][ j ]为第一排亮了i个灯,第二排亮了j个灯,距离目标状态的期望天数。显然 i >= m ,j >= m时 , dp[ i ][ j ] = 0 。 状态转移 : 第一排亮了a个灯,a 在[ 0 , n - i] 之间,第二排亮了b个灯 , b 在

zoj 3228 ac自动机

给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现,1为不可重叠出现。 Sample Input ab 2 0 ab 1 ab abababac 2 0 aba 1 aba abcdefghijklmnopqrstuvwxyz 3 0 abc 1 def 1 jmn Sample Output Case 1 1 1 Case 2

ZOJ Monthly, August 2014小记

最近太忙太忙,只能抽时间写几道简单题。不过我倒是明白要想水平提高不看题解是最好的了。 A  我只能死找规律了,无法证明 int a[50002][2] ;vector< vector<int> > gmax , gmin ;int main(){int n , i , j , k , cmax , cmin ;while(cin>>n){/* g

题目1380:lucky number

题目1380:lucky number 时间限制:3 秒 内存限制:3 兆 特殊判题:否 提交:2839 解决:300 题目描述: 每个人有自己的lucky number,小A也一样。不过他的lucky number定义不一样。他认为一个序列中某些数出现的次数为n的话,都是他的lucky number。但是,现在这个序列很大,他无法快速找到所有lucky number。既然

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。

Jenkins 通过 Version Number Plugin 自动生成和管理构建的版本号

步骤 1:安装 Version Number Plugin 登录 Jenkins 的管理界面。进入 “Manage Jenkins” -> “Manage Plugins”。在 “Available” 选项卡中搜索 “Version Number Plugin”。选中并安装插件,完成后可能需要重启 Jenkins。 步骤 2:配置版本号生成 打开项目配置页面。在下方找到 “Build Env

hdu2072(string的应用)

单词数 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 25447    Accepted Submission(s): 5957 Problem Description lily的好朋友xiaoou333最近很空,他