您的位置:首页 > 运维架构

TOPCODER SRM 686 div2 1000

2016-05-27 20:54 471 查看
// TOPCODER SRM 686 div2 1000

Problem Statement

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

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

Examples

"(())("
Returns: 2

"()"和"(())"两个。

"())"
Returns: 1

只有"()"。

")((("
Returns: 0

没有合法的子序列。

"()()()()()()()()(())))(()()()()))())"
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
[0][1];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: