社区讨论

求大佬看我口胡

P7914[CSP-S 2021] 括号序列参与者 3已保存回复 3

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@lobi1kdd
此快照首次捕获于
2023/10/29 21:20
2 年前
此快照最后确认于
2023/11/04 02:33
2 年前
查看原帖
设状态f[id,a,b,c,d]f[id, a, b, c, d]表示做了前idid个,当前字符代号为aa,连续星星数为bb,是否缺少右括号为cc,缺少数量为dd
然后根据当前字符分类讨论转移
状态数过多不好压,可以用map维护dp状态数组
时间复杂度Θ(6n2k)\Theta(6n^2k),还有带一个map的log\log
不知道是否正确
CPP
//Per aspera ad astra.
//1004535809
#include <map>
#include <cstdio>
#include <vector>
#include <algorithm>
#define re register
#define ll long long
using namespace std;
const int N = 5e2 + 5, P = 1e9 + 7;
int n, k; char str[N];
template<class T> T cmax(re T x, re T y) {return x > y ? x : y;}
template<class T> T cmin(re T x, re T y) {return x < y ? x : y;}
struct OI {
	int rp, score;
}CSPS2021;
struct id {
	int i, a, b, c, d;
};
map<id, int> f;
//i:浣嶇疆  a:褰撳墠瀛楃{*0,(1,)2}  b:鏄熷彿鏁伴噺  c:涓嶅皯0/缂哄彸鎷彿1  d:缂哄皯鐨勬暟閲?
inline bool operator < (re id x, re id y) {
	if (x.i ^ y.i) return x.i < y.i;
	if (x.a ^ y.a) return x.a < y.a;
	if (x.b ^ y.b) return x.b < y.b;
	if (x.c ^ y.c) return x.c < y.c;
	return x.d < y.d;
}
signed main() {
	++CSPS2021.rp, ++CSPS2021.score;
	freopen("bracket.in", "r", stdin);
	freopen("bracket.out", "w", stdout);
	scanf("%d%d%s", &n, &k, str + 1);
	if (str[1] != '?') {
		if (str[1] == '*') f[(id){1, 0, 1, 0, 0}] = 1;
		if (str[1] == '(') f[(id){1, 1, 0, 1, 1}] = 1;
		if (str[1] == ')')return !printf("0\n");
	}
	else f[(id){1, 0, 1, 0, 0}] = f[(id){1, 1, 0, 1, 1}] = 1;
	for (re int i = 2; i <= n; ++i)
		if (str[i] != '?') {
			if (str[i] == '*') {
				for (re int d = 0; d < 3; ++d)
				for (re int a = 0; a <= (d ? 0 : k - 1); ++a)
					for (re int b = 0; b < 2; ++b)
						for (re int c = 0; c <= (b ? n : 0); ++c)
							if (f.count((id){i - 1, d, a, b, c}))
								f[(id){i, 0, a + 1, b, c}] = (f[(id){i, 0, a + 1, b, c}] + f[(id){i - 1, d, a, b, c}]) % P;
			}
			else if (str[i] == '(') {
				for (re int d = 0; d < 3; ++d)
				for (re int a = 0; a <= (d ? 0 : k); ++a)
					for (re int b = 0; b < 2; ++b)
						for(re int c = 0; c <= (b ? n : 0); ++c) {
							if (!b && f.count((id){i - 1, d, a, b, c}))
								f[(id){i, 1, 0, 1, 1}] = (f[(id){i, 1, 0, 1, 1}] + f[(id){i - 1, d, a, b, c}]) % P;
							else if (b == 1 && c < n && f.count((id){i - 1, d, a, b, c}))
								f[(id){i, 1, 0, 1, c + 1}] = (f[(id){i, 1, 0, 1, c + 1}] + f[(id){i - 1, d, a, b, c}]) % P;
						}
				
			}
			else if (str[i] == ')') {
				for (re int d = 0; d < 3; ++d)
				for (re int a = 0; a <= (d ? 0 : k); ++a)
					for (re int b = 0; b < 2; ++b)
						for (re int c = 0; c <= (b ? n : 0); ++c) {
							if (b == 1 && c > 0 && f.count((id){i - 1, d, a, b, c}))
								f[(id){i, 2, 0, b, c - 1}] = (f[(id){i, 2, 0, b, c - 1}] + f[(id){i - 1, d, a, b, c}]) % P;
							else if (b == 1 && f.count((id){i - 1, d, a, b, c}))
								f[(id){i, 2, 0, 0, 0}] = (f[(id){i, 2, 0, 0, 0}] + f[(id){i - 1, d, a, b, c}]) % P;
						}
			}
		}
		else if (str[i] == '?') {
			for (re int d = 0; d < 3; ++d)
				for (re int a = 0; a <= (d ? 0 : k - 1); ++a)
					for (re int b = 0; b < 2; ++b)
						for (re int c = 0; c <= (b ? n : 0); ++c)
							if (f.count((id){i - 1, d, a, b, c}))
								f[(id){i, 0, a + 1, b, c}] = (f[(id){i, 0, a + 1, b, c}] + f[(id){i - 1, d, a, b, c}]) % P;
			for (re int d = 0; d < 3; ++d)
				for (re int a = 0; a <= (d ? 0 : k); ++a)
					for (re int b = 0; b < 2; ++b)
						for(re int c = 0; c <= (b ? n : 0); ++c) {
							if (!b && f.count((id){i - 1, d, a, b, c}))
								f[(id){i, 1, 0, 1, 1}] = (f[(id){i, 1, 0, 1, 1}] + f[(id){i - 1, d, a, b, c}]) % P;
							else if (b == 1 && c < n && f.count((id){i - 1, d, a, b, c}))
								f[(id){i, 1, 0, 1, c + 1}] = (f[(id){i, 1, 0, 1, c + 1}] + f[(id){i - 1, d, a, b, c}]) % P;
						}
			for (re int d = 0; d < 3; ++d)
				for (re int a = 0; a <= (d ? 0 : k); ++a)
					for (re int b = 0; b < 2; ++b)
						for (re int c = 0; c <= (b ? n : 0); ++c) {
							if (b == 1 && c > 0 && f.count((id){i - 1, d, a, b, c}))
								f[(id){i, 2, 0, b, c - 1}] = (f[(id){i, 2, 0, b, c - 1}] + f[(id){i - 1, d, a, b, c}]) % P;
							else if (b == 1 && f.count((id){i - 1, d, a, b, c}))
								f[(id){i, 2, 0, 0, 0}] = (f[(id){i, 2, 0, 0, 0}] + f[(id){i - 1, d, a, b, c}]) % P;
						}
		}
	/*for (re int i = 1; i <= n; ++i)
		for (re int d = 0; d < 3; ++d)
			for (re int a = 0; a <= k; ++a)
				for (re int b = 0; b < 2; ++b)
					for (re int c = 0; c <= n; ++c)
						if (f.count((id){i, d, a, b, c}))
							printf("%d %d %d %d %d: %d\n", i, d, a, b, c, f[(id){i, d, a, b, c}]);*/
	//map<id, int>::iterator it = f.begin();
	//for (; it != f.end(); ++it) printf("%d %d %d %d %d: %d\n", it->first.i, it->first.a, it->first.b, it->first.c, it->first.d, it->second); printf("\n");
	re int ans = 0;
	if (str[n] != '?') {
		re int d;
		if (str[n] == '*') d = 0;
		else if (str[n] == '(') d = 1;
		else if (str[n] == ')') d = 2;
		for (re int a = 0; a <= (d ? n : 0); ++a)
			if (f.count((id){n, d, a, 0, 0}))
				ans = (ans + f[(id){n, d, a, 0, 0}]) % P;
	}
	else
		for (re int d = 0; d < 3; ++d)
			for (re int a = 0; a <= (d ? n : 0); ++a)
				if (f.count((id){n, d, a, 0, 0}))
					ans = (ans + f[(id){n, d, a, 0, 0}]) % P;
	printf("%d\n", ans);
	return 392699 ^ 392699;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...