CSP2021补题-廊桥分配 括号序列 回文
点击查看代码
#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;
}
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;
}
点击查看代码
// 先找到
#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;
}