专栏文章

题解:P7248 [BalticOI 2012] 括号 (Day1)

P7248题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miq2s88i
此快照首次捕获于
2025/12/03 22:01
3 个月前
此快照最后确认于
2025/12/03 22:01
3 个月前
查看原文

P7248 [BalticOI 2012] 括号 (Day1) 题解:

题意非常好理解,相信大家都能看懂,这里不再赘述,直接说思路。

1.思路:

题目中规定只能用 ( 来替换 [] ,所以,当给定的不合法的字符串中左括号 ( 的数量小于右括号 ) 的数量时,显然没有能转化为它的合法字符串。
所以,下面只讨论左括号数量大于右括号数量的字符串。

举个例子:

对于 ()(( 这个不合法的字符串来说:它只能由 ()[] 转换而来。
但如果我们将这个合法的字符串中的所有 [ 转换为 (] 转换为 ) 就可以得到一个只包含圆括号的合法字符串: ()()
于是题目中的问题就转换为了将原字符串中的不匹配的左括号匹配起来的方案数。显然用动态规划求解。
dpi,jdp_{i,j} 为第 ii 个位置还有 jj 个未匹配的 ( 时的方案数,则有:
dpi,j=dpi1,j1dp_{i,j}=dp_{i-1,j-1}(此字符为 )
dpi,j=dpi1,j1+dpi1,j+1dp_{i,j}=dp_{i-1,j-1}+dp_{i-1,j+1}(此字符为(
由于内存限制,使用滚动数组。
该说的都说完了,上代码:

2.Code:

码风很烂,将就着看。
CPP
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 300005;
const int MOD = 1000000009;
int n;
char ch;
int dp[3][MAXN];

int main(){
    ios::sync_with_stdio(0);
    cin>>n;
    dp[0][0]=1;
    for(register int i=1;i<=n;i++){
        cin>>ch;
        for(register int j=0;j<=min(i,n-i);j++){
            if (!j || ch == ')') dp[i & 1][j] = dp[(i+1)&1][j + 1];
			else dp[i & 1][j] = (dp[(i+1)&1][j + 1] + dp[(i+1)&1][j - 1]) % MOD;
        }
    }
    cout << dp[n & 1][0] << '\n';
	return 0;
}

全文完。 点个赞呗!!!

评论

0 条评论,欢迎与作者交流。

正在加载评论...