Loading

MX galaxy Day14

barcket

区间 \(DP\)
转移时枚举左端点与谁匹配即可。
赛场上比较纯,多设了一维状态。

点击查看

#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)

const int _ = 1000 + 7;
const int mod = 1e5;
typedef long long ll;

int n, c[_]; ll dp[_][_][2]; char s[_];

int main() {
	scanf("%s", s + 1); n = std::strlen(s + 1);
	lep(i, 1, n + 1) {
		if (s[i] == '(') c[i] = 1;
		else if (s[i] == ')') c[i] = -1;
		else if (s[i] == '[') c[i] = 2;
		else if (s[i] == ']') c[i] = -2;
		else if (s[i] == '{') c[i] = 3;
		else if (s[i] == '}') c[i] = -3;
		else if (s[i] == '<') c[i] = 4;
		else if (s[i] == '>') c[i] = -4;
		dp[i][i - 1][1] = 1;
	}
	for (int len = 2; len <= n; len += 2) lep(l, 1, n - len + 1) {
		int r = l + len - 1;
		
		if (c[l] and c[r]) dp[l][r][0] = dp[l + 1][r - 1][1] * (c[l] > 0 and c[r] < 0 and c[l] + c[r] == 0);
		else if (c[l]) dp[l][r][0] = dp[l + 1][r - 1][1] * (c[l] > 0);
		else if (c[r]) dp[l][r][0] = dp[l + 1][r - 1][1] * (c[r] < 0);
		else dp[l][r][0] = dp[l + 1][r - 1][1] * 4;
		
		for (int k = l + 1; k <= r; k += 2) dp[l][r][1] += dp[l][k][0] * dp[k + 1][r][1];
	}
	
	printf("%lld\n", dp[1][n][1]);
	return 0;
}

sequence

考虑导弹拦截。
\(f_i\) 表示长度为 \(i\) 的子序列末尾最小能是多少。
然后发现转移形如,区间填平,区间后移一位然后插入一个值,区间删除。
这些都可以用 \(set\) 维护。

点击查看

#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)

const int _ = 2e5 + 7;
const int inf = 2e9;
typedef long long ll;
typedef std::pair<int, int> PII;

int n, l, r, ans, tmp;
std::multiset<PII> S;

inline void Del(int r) {
	auto pr = S.upper_bound({r, inf}), nw = pr;
	while (pr != S.end())
		nw = pr, ++pr, tmp -= nw->second, S.erase(nw);
}
inline void Add(int l) {
	int tot = 1;
	auto pl = S.begin(), nw = pl;
	while (pl != S.end() and pl->first <= l)
		tot += pl->second, nw = pl, ++pl, S.erase(nw);
	S.insert({l, tot}), ++tmp;
}

int main() {
#ifndef DEBUG
	freopen("sequence.in", "r", stdin);
	freopen("sequence.out","w",stdout);
#endif
	scanf("%d", & n);
	lep(i, 1, n) {
		scanf("%d%d", & l, & r);
		Del(r), Add(l); ans = std::max(ans, tmp);
	}
	
	printf("%d\n", ans);
	return 0;
}

posted @ 2025-07-30 21:45  qkhm  阅读(11)  评论(0)    收藏  举报