TOPCODER SRM 686 div2 1000
2016-05-27 20:54
471 查看
// TOPCODER SRM 686 div2 1000
子序列可以不连续;合法即括号序列的合法;答案模 1,000,000,007。
"()"和"(())"两个。
只有"()"。
没有合法的子序列。
这道问题跟 CODEFROCES 645E 的模型是同一个。
http://www.cnblogs.com/gu-castle/p/5535969.html
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];
}
}
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];
}
}
相关文章推荐
- Learning OpenCV: cvSmooth processing
- 常用网站
- linux
- 73条日常Linux shell命令汇总
- bash 提示
- docker学习笔记2-docker入门
- Learning OpenCV: read video and add onTrackSlider
- Hadoop整合Hive之API封装及操作
- 页面跳转(pop返回多个ViewController)
- 搭建Apache Server +Tomcat 简单集群环境,实现session复制
- CentOS 6.5 下vim 配置
- OpenCV学习离散傅里叶变换(DFT)
- 小型电子商务网站数据管理系统
- android MVP——mvp架构的应用和优化
- centos7之lamp环境搭建
- CentOS6.5安装JDK
- centos之lnmp
- 反向代理之HAProxy的简单应用
- tomcat8 故障排查
- [Linux] Zip 命令归纳