Loading

题解「AGC048B Bracket Score」

题面

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;
}
posted @ 2020-11-13 21:11  GoPoux  阅读(156)  评论(0编辑  收藏  举报