题解「AGC048B Bracket Score」
题面
题解
发现一对匹配的括号的间距一定是偶数,即它们两个的位置的奇偶性不同。还能发现,一旦每个位置上的括号类型(即是小括号还是方括号)确定且一对匹配的括号的间距是偶数,一定能找到一种确定括号朝向的方法使得序列合法。
考虑堆贪心,先全部选择小括号,对于每个位置,计算将它改为方括号对答案的影响。将奇数位置和偶数位置的影响分别丢进两个堆中,每次分别取出两个堆的堆顶,将对应的位置改为方括号,直到再取堆顶答案不会更优。
\(\text{Code}:\)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#define Rint register int
#define INF 0x3f3f3f3f
using namespace std;
typedef long long lxl;
const int maxn=1e5+5;
template <typename T>
inline void read(T &x)
{
x=0;T f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
x*=f;
}
int n;
int a[maxn],b[maxn];
priority_queue<int> q[2];
lxl ans;
int main()
{
#ifndef ONLINE_JUDGE
freopen("AGC048B.in","r",stdin);
#endif
read(n);
for(int i=1;i<=n;++i) read(a[i]),ans+=a[i];
for(int i=1;i<=n;++i)
read(b[i]),q[i&1].push(b[i]-a[i]);
while(!q[0].empty())
{
int val=q[0].top()+q[1].top();
q[0].pop();q[1].pop();
if(val<=0) break;
ans+=val;
}
printf("%lld\n",ans);
return 0;
}