Atcoder Beginner Contest 312
1.Atcoder Beginner Contest 312
2.Educational Codeforces Round 152 (Rated for Div. 2)3.Codeforces Round 889 (Div. 2)4.Codeforces Round 888 (Div. 3)5.Codeforces Round 847 (Div. 3)6.Codeforces Round 890 (Div. 2)7.Codeforces Round 892 (Div. 2)8.Codeforces Round 893 (Div. 2)9.Educational Codeforces Round 15310.Codeforces Round 891 (Div. 3)11.Codeforces Round 894 (Div. 3)12.Educational Codeforces Round 154 (Rated for Div. 2)13.Codeforces Round 896 (Div. 2)14.Codeforces Round 855 (Div. 3)15.codeforces round 895 (div. 3)16.Codeforces Round 900 (Div. 3)17.Codeforces Round 901 (Div. 2)18.Codeforces Round 903 (Div. 3)D
题意:
给你一串由( ) ?
三种字符构成的字符串,?
可以变化成(
或者 )
问你有多少种方案把序列变成一个合法序列?
思路:
一个合法的括号序列,在每个位置上它的左括号一定要大于等于右括号的数量并且最后两个括号的数量应该相等,所以定义f[i][j]
为枚举到第i
个位置时左括号减右括号的差值
当s[i] == '(
时,当前方案数应该等于前i - 1
个字符中减去一个(
,反过来也一样。当s[i] == '?
时此时既可以为左括号也可以为右括号,所以方案数为两者之和。
#include <bits/stdc++.h>
using namespace std;
#define more ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N = 2e5 + 5, MOD = 998244353, inf = 0x3f3f3f3f;
const long long INF = 1e18;
typedef long long LL;
typedef unsigned long long usLL;
typedef pair<int, int> PII;
int f[3010][3010]; // 前i个中,左括号 - 右括号的差为j的方案数
void solve()
{
string s; cin >> s;
f[0][0] = 1;
for (int i = 1; i <= s.size(); i++)
{
for (int j = 0; j <= i; j++)
{
if (s[i - 1] == '(') f[i][j] = f[i - 1][j - 1] % MOD;
if (s[i - 1] == ')') f[i][j] = f[i - 1][j + 1] % MOD;
if (s[i - 1] == '?') f[i][j] = (f[i - 1][j - 1] + f[i - 1][j + 1]) % MOD;
}
}
cout << f[s.size()][0] << endl;
}
int main()
{
more;
// int T;
// cin >> T;
// while (T--)
// {
// solve();
// }
solve();
return 0;
}
本文作者:自动机
本文链接:https://www.cnblogs.com/monituihuo/articles/17591917.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步