TOPCODER SRM 686 div2 1000

// TOPCODER SRM 686 div2 1000

Problem Statement

给出一个至多长 100 的字符串,仅包含 (),问其中有多少个不重复的,合法的括号子序列。

子序列可以不连续;合法即括号序列的合法;答案模 1,000,000,007。

Examples

"(())("
Returns: 2

Correct non-empty bracket subsequences are "()" and "(())".

"())"
Returns: 1

Only "()" is suitable.

")((("
Returns: 0

There are no non-empty correct bracket subsequences.

"()()()()()()()()(())))(()()()()))())"
Returns: 364675
"()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()"
Returns: 122826009

Solution

f[i][j][c] 表示对于前 i 个字符组成的串,左括号比右括号多 j 个,并且以 c 为结尾的子序列的个数。注意这里的状态存的不是所有的子序列,在转移的时候为了让括号合法,仅转移 j >= 0 的那些状态,这个时候 f[i][j][c] 的值比所有的子序列要少,而 f[i][0][1] 就是前 i 个字符组成的串中,合法的,不重复子序列数目。

这道问题跟 CODEFROCES 645E 的模型是同一个。

http://www.cnblogs.com/gu-castle/p/5535969.html

Code

  1. public class BracketSequenceDiv2 {


  2. static final int MOD = (int) 1e9 + 7; 


  3. int modAdd(int a, int b) { 

  4. int sum = a + b; 

  5. if (sum >= MOD) { 

  6. sum -= MOD; 



  7. return sum; 




  8. public int count(String str) { 

  9. int n = str.length(); 

  10. int[][][] dp = new int[n + 1][n + 1][2]; 


  11. for (int i = 1; i <= n; ++i) { 

  12. char ch = str.charAt(i - 1); 

  13. if (ch == ‘(‘) { 

  14. dp[i][1][0] = modAdd(dp[i - 1][0][0], dp[i - 1][0][1]); 

  15. dp[i][1][0] = modAdd(dp[i][1][0], 1); 

  16. for (int j = 2; j <= i; ++j) { 

  17. dp[i][j][0] = modAdd(dp[i - 1][j - 1][0], 

  18. dp[i - 1][j - 1][1]); 



  19. for (int j = 0; j <= i; ++j) { 

  20. dp[i][j][1] = dp[i - 1][j][1]; 





  21. else { // ch == ‘)‘ 

  22. for (int j = 0; j < i; ++j) { 

  23. dp[i][j][1] = modAdd(dp[i - 1][j + 1][0], 

  24. dp[i - 1][j + 1][1]); 



  25. for (int j = 0; j <= i; ++j) { 

  26. dp[i][j][0] = dp[i - 1][j][0]; 







  27. return dp[n][0][1]; 





时间: 2024-08-05 19:03:28

TOPCODER SRM 686 div2 1000的相关文章

Topcoder SRM 648 Div2 1000

Problem 给一个长度为N的字符串S,S只含有'A'.'B'.'C'三种元素.给定一个K,要求返回字符串S,使得S中恰好有K对pair(i,j)满足 0=<i<j<N,且 S[i]<S[j].若不存在,则返回空串. Limits Time Limit(ms): 2000 Memory Limit(MB): 256 N: [3, 30] K: [0, N*(N-1)/2 ] Solution 设S中含有n1个'A',n2个'B',n3个'C',设num=n1*n2+n1*n3+n

Topcoder Srm 673 Div2 1000 BearPermutations2

\(>Topcoder \space Srm \space 673 \space Div2 \space 1000 \space BearPermutations2<\) 题目大意 : 对于一个长度为 \(n\) 的排列,定义其的贡献为对其建笛卡尔树,树上有两个儿子的节点其左右儿子在原排列中的距离之和,给出 \(n, Mod\),求所有长度为 \(n\) 的排列的贡献之和对 \(Mod\) 取模的值 \(1 \leq n \leq 100\) 解题思路 : 考虑一个最暴力的 \(dp\) ,设

Topcoder SRM 654 Div2 1000

Problem 给一个长度为N(N∈[1,2000])的数列An(An∈[?100,100]),设ans=A1?A2?...?An,下面进行M(M∈[1,2000])次操作,每次将A的p[i]的值修改为v[i],即A[p[i]]=v[i],每次只允许加入最多2个括号进入ans等式,问ans的最大值可以是多少? Solution dp.. 设dp[i][j]表示从 1 到 i-1 已经有 j 个括弧时候的最大值,j=0时表示没有括弧,j=1时表示(这样子,j=2时表示(( 这个样子,j=3时表示(

topcoder SRM 625 DIV2 AddMultiply

由于题目告诉肯定至少存在一种解, 故只需要根据条件遍历一下, vector <int> makeExpression(int y) { vector<int> res; for(int i = -1000; i <=1000; ++ i){ for(int j = -1000; j <= 1000; ++ j){ if(i!=0 && i!=1 && j!=0&& j!=1 ){ int k = y-i*j; if(k&g

topcoder SRM 628 DIV2 BishopMove

题目比较简单. 注意看测试用例2,给的提示 Please note that this is the largest possible return value: whenever there is a solution, there is a solution that uses at most two moves. 最多只有两步 #include <vector> #include <string> #include <list> #include <map&

topcoder SRM 618 DIV2 WritingWords

只需要对word遍历一遍即可 int write(string word) { int cnt = 0; for(int i = 0 ; i < word.length(); ++ i){ cnt+=word[i]-'A'+1; } return cnt; } topcoder SRM 618 DIV2 WritingWords,布布扣,bubuko.com

topcoder SRM 618 DIV2 MovingRooksDiv2

一开始Y1,Y2两个参数看不懂,再看一遍题目后才知道,vector<int>索引代表是行数,值代表的是列 此题数据量不大,直接深度搜索即可 注意这里深度搜索的访问标识不是以前的索引和元素,而是一个交换元素后的整个状态vector<int>,这样可以避免重复元素的搜索 set<vector<int> > visit; bool flag; void dfs(vector<int>& src, vector<int>& d

topcoder SRM 618 DIV2 LongWordsDiv2

此题给出的条件是: (1)word的每个字母都是大写字母(此条件可以忽略,题目给的输入都是大写字母) (2) 相等字符不能连续,即不能出现AABC的连续相同的情况 (3)word中不存在字母组成xyxy的形式,即不存在第一个字符和第3个字符相等同时第2个字符和第4个字符相等的情况 对于第(2)种情况,只需要考虑word[i]!=word[i-1]即可 对于第(3)种情况,用一个4重循环遍历每种可能的情况,然后第一个字符和第3个字符相等同时第2个字符和第4个字符相等,则输出“DisLikes”即可

topcoder srm 628 div2 250 500

做了一道题,对了,但是还是掉分了. 第二道题也做了,但是没有交上,不知道对错. 后来交上以后发现少判断了一个条件,改过之后就对了. 第一道题爆搜的,有点麻烦了,其实几行代码就行. 250贴代码: 1 #include <iostream> 2 #include <cstring> 3 #include <queue> 4 #include <cmath> 5 #include <cstdio> 6 #include <algorithm&g