https://atcoder.jp/contests/agc048/tasks
B - Bracket Score
题意:给定A,B数组,要用 ‘(’, ‘)’, ‘[’, ‘]’ 构造出合法的括号序列,若位置 i 为 ‘(’ 或 ‘)’,则该位置贡献 Ai,否则贡献 Bi,求最大总贡献。
贪心
先把所有位置上都放小括号,由于题目规定了 n 为偶数,所以必定合法。
再尝试修改一些位置上为中括号,每次选择两个间隔为偶数,且都为小括号的位置,并修改,这样每对小括号以及每对中括号的长度都为偶数,必定能够构造出合法序列。
所以只要贪心地每次选择一对修改后贡献最大的位置变为中括号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <bits/stdc++.h> #define debug(x) cout << ##x << ":\t" << (x) << endl; using namespace std; #define ll long long const int N = 2e6 + 10; const int INF = 0x3f3f3f3f; const ll inf = 0x3f3f3f3f3f3f3f3f; const ll mod = 998244353; int n; ll a[N], b[N]; ll ans; priority_queue<ll>q[2]; int main() { scanf("%d", &n); for (int i = 1; i <= n; i++)scanf("%lld", &a[i]), ans += a[i]; for (int i = 1; i <= n; i++)scanf("%lld", &b[i]); for (int i = 1; i <= n; i++) { q[i & 1].push(b[i] - a[i]); } while (1) { if (!q[0].empty() && q[0].top() + q[1].top() > 0) { ans += q[0].top() + q[1].top(); q[0].pop(); q[1].pop(); } else break; } printf("%lld\n", ans); return 0; }
|