TOPCODER SRM 686 div2 1000
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
- public class BracketSequenceDiv2 {
- static final int MOD = (int) 1e9 + 7;
-
- int modAdd(int a, int b) {
- int sum = a + b;
- if (sum >= MOD) {
- sum -= MOD;
- }
- return sum;
- }
-
- public int count(String str) {
- int n = str.length();
- int[][][] dp = new int[n + 1][n + 1][2];
-
- for (int i = 1; i <= n; ++i) {
- char ch = str.charAt(i - 1);
- if (ch == ‘(‘) {
- dp[i][1][0] = modAdd(dp[i - 1][0][0], dp[i - 1][0][1]);
- dp[i][1][0] = modAdd(dp[i][1][0], 1);
- for (int j = 2; j <= i; ++j) {
- dp[i][j][0] = modAdd(dp[i - 1][j - 1][0],
- dp[i - 1][j - 1][1]);
- }
- for (int j = 0; j <= i; ++j) {
- dp[i][j][1] = dp[i - 1][j][1];
- }
- }
- else { // ch == ‘)‘
- for (int j = 0; j < i; ++j) {
- dp[i][j][1] = modAdd(dp[i - 1][j + 1][0],
- dp[i - 1][j + 1][1]);
- }
- for (int j = 0; j <= i; ++j) {
- dp[i][j][0] = dp[i - 1][j][0];
- }
- }
- }
- return dp[n][0][1];
- }
- }
以上是关于TOPCODER SRM 686 div2 1000的主要内容,如果未能解决你的问题,请参考以下文章
Topcoder Srm 673 Div2 1000 BearPermutations2
Topcoder--SRM698-Div2 : SubtreeSum
TopCoder SRM 717 Div2 C.DerangementsDiv2[数论][容斥原理][错排]