CSP2021补题-廊桥分配 括号序列 回文

CSP-S 2021廊桥分配

点击查看代码
#include <queue>
#include <utility>
#include <stdio.h>
#include <string.h>
#include <algorithm>
const int N = 1e5 + 5;
typedef std::pair<int, int> PII;
PII a[N], b[N]; int n, ma, mb, suma[N], sumb[N], res;
void solve(int m, std::pair<int, int> p[N], int *sump) {
	std::priority_queue<PII, std::vector<PII>, std::greater<PII> > heap1, heap2;
	// heap: [停机场,离开时间] heap1: first=离开时间, heap2: first=停机场
	int tot = 0;
	for(int i = 1; i <= m; i ++) {
		while(heap1.size() && heap1.top().first < p[i].first) // 将所有的之前离开的放入可使用队列
			heap2.push({heap1.top().second, heap1.top().first}), heap1.pop();
		if(heap2.empty()) // 新开一个
			sump[++ tot] = 1, heap1.push({p[i].second, tot});
		else // 尽量放入编号小的
			sump[heap2.top().first] ++, heap1.push({p[i].second, heap2.top().first}), heap2.pop();
	}
	for(int i = 1; i <= n; i ++) sump[i] += sump[i - 1]; // 累计所有飞机
}
int main() {
// 	freopen("airport.in", "r", stdin);
// 	freopen("airport.out", "w", stdout);
	scanf("%d%d%d", &n, &ma, &mb);
	for(int i = 1; i <= ma; i ++) scanf("%d%d", &a[i].first, &a[i].second);
	for(int i = 1; i <= mb; i ++) scanf("%d%d", &b[i].first, &b[i].second);
	std::sort(a + 1, a + ma + 1), std::sort(b + 1, b + mb + 1), solve(ma, a, suma), solve(mb, b, sumb);
	for(int i = 0; i <= n; i ++) res = std::max(res, suma[i] + sumb[n - i]);
	printf("%d\n", res), fclose(stdin), fclose(stdout);
	return 0;
}

P7914 CSP-S2021 括号序列

f[l][r][]: 区间DP
0: ...
1: ( 两边是括号 )
2: (..)(..)
3: (..)(..)(..)
4: (..)(..)
5: (..)(..)***
注意: "*"不可以由两个区间相连构成

点击查看代码
// f[l][r][]: 区间DP
// 0: **...**
// 1: ( 两边是括号 )
// 2: (..)***(..)***
// 3: (..)***(..)***(..)
// 4: ***(..)***(..)
// 5: ***(..)***(..)***
// 注意: "*"不可以由两个区间相连构成
#pragma GCC optimize("Ofast")
#include <stdio.h>
#include <string.h>
typedef long long LL;
const int N = 505, mod = 1e9 + 7;
int n, m, f[N][N][6]; char str[N];
int main() {
	scanf("%d%d%s", &n, &m, str + 1);
	for(int i = 1; i <= n; i ++) f[i][i-1][0] = 1;
	for(int len = 1; len <= n; len ++)
		for(int l = 1, r = len; r <= n; l ++, r ++) {
			if(len <= m) f[l][r][0] = f[l][r - 1][0] && (str[r] == '?' || str[r] == '*');
			if(len >= 2) {
				if((str[l] == '(' || str[l] == '?') && (str[r] == ')' || str[r] == '?'))
					f[l][r][1] = ((LL)f[l+1][r-1][0] + f[l+1][r-1][2] + f[l+1][r-1][3] + f[l+1][r-1][4]) % mod;
				for(int k = l; k < r; k ++) {
					(f[l][r][2] += (LL)f[l][k][3] * f[k+1][r][0] % mod) %= mod;
					(f[l][r][3] += (LL)(f[l][k][2] + f[l][k][3]) * f[k+1][r][1] %mod) %= mod;
					(f[l][r][4] += (LL)(f[l][k][4] + f[l][k][5]) * f[k+1][r][1] %mod) %= mod;
					(f[l][r][5] += (LL)f[l][k][4] * f[k+1][r][0] % mod) %= mod;
				}
			}
			(f[l][r][5] += f[l][r][0]) %= mod;
			(f[l][r][3] += f[l][r][1]) %= mod;
		}
	printf("%d\n", f[1][n][3]);
	return 0;
}

P7915 CSP-S 2021回文

点击查看代码
// 先找到
#include <stdio.h>
#include <string.h>
const int N = 1e6 + 5;
int T, n, t, p[N];
char now[N], res[N];
struct {
	int q[N], hh, tt;
	void pop_back() { tt --; }
	void pop_front() { hh ++; }
	int back() { return q[tt]; }
	int front() { return q[hh]; }
	bool check() { return hh < tt; }
	bool empty() { return hh > tt; }
	void clear() { hh = 0, tt = -1; }
	void push(int x) { q[++ tt] = x; }
} l, r;
bool solve() {
	for(int i = 2, j = 2 * n - 1; ; i ++, j --) {
		if(l.empty() && r.empty()) break;
		else if(l.empty())
			if(r.back() == r.front())				r.pop_back(), r.pop_front(), now[i] = 'R', now[j] = 'R';
			else return false;
		else if(r.empty())
			if(l.back() == l.front())				l.pop_back(), l.pop_front(), now[i] = 'L', now[j] = 'L';
			else return false;
		else if(l.back() == l.front() && l.check())	l.pop_back(), l.pop_front(), now[i] = 'L', now[j] = 'L';
		else if(l.back() == r.front())				l.pop_back(), r.pop_front(), now[i] = 'L', now[j] = 'R';
		else if(r.back() == l.front())				r.pop_back(), l.pop_front(), now[i] = 'R', now[j] = 'L';
		else if(r.back() == r.front() && r.check())	r.pop_back(), r.pop_front(), now[i] = 'R', now[j] = 'R';
		else return false;
	}
	return true;
}
int main() {
	scanf("%d", &T);
	while(T --) {
		scanf("%d", &n), l.clear(), r.clear();
		for(int i = 1; i <= 2 * n; i ++) scanf("%d", p + i);
		for(int i = 2; i <= 2 * n; i ++) if(p[1] == p[i]) { t = i; break; }
		for(int i = t - 1; i >= 2; i --) l.push(p[i]);
		for(int i = t + 1; i <= 2 * n; i ++) r.push(p[i]);
		if(solve()) now[1] = now[2 * n] = 'L', now[2 * n + 1] = 0, puts(now + 1);
		else {
			l.clear(), r.clear();
			for(int i = 1; i < 2 * n; i ++) if(p[2 * n] == p[i]) { t = i; break; }
			for(int i = t - 1; i; i --) l.push(p[i]);
			for(int i = t + 1; i < 2 * n; i ++) r.push(p[i]);
			if(solve()) now[1] = 'R', now[2 * n] = 'L', now[2 * n + 1] = 0, puts(now + 1);
			else puts("-1");
		}
	}
	return 0;
}
posted @ 2022-10-10 12:33  azzc  阅读(37)  评论(0编辑  收藏  举报