正题
题目链接:https://atcoder.jp/contests/agc048/tasks/agc048_b
题目大意
长度为 n n n的合法括号序列可以包含 [ . . . ] [...] [...]和 ( . . . ) (...) (...)。
如果在第 i i i个位置是 ′ ( ′ ' ( ' ′ ( ′ 或者 ′ ) ′ ' ) ' ′ ) ′那么可以获得 a i a_i ai的权值,否则获得 b i b_i bi的权值。
求一个合法的括号序列使得权值最大。
解题思路
首先对于每对匹配的括号肯定是一奇一偶的,有一个结论就是只要两种括号的奇和偶数上括号的个数相同,那么就一定有一种合法匹配。
大致的理解方法就是,对于每一种方案至少存在一对相邻的同种括号,否则就不满足以上性质,然后就可以将这对括号删去。重复以上过程就可以证明该结论
那么考虑贪心选取,对于每个位置我们先默认选择小括号,那么如果转换的话就会获得 w i = a i − b i w_i=a_i-b_i wi=ai−bi的价值。然后每次选取一奇一偶的 w i w_i wi,把奇偶的 w i w_i wi分开排序选取即可。
时间复杂度 O ( n log n ) O(nlog n) O(nlogn)
c o d e code code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define ll long long using namespace std; const ll N=1e5+10; ll n,a[N],b[N],sum,ans; vector<ll > v[2]; int main() { scanf("%lld",&n); for(ll i=1;i<=n;i++)scanf("%lld",&a[i]); for(ll i=1;i<=n;i++)scanf("%lld",&b[i]),sum+=b[i]; for(ll i=1;i<=n;i++) v[i&1].push_back(a[i]-b[i]); sort(v[0].begin(),v[0].end()); sort(v[1].begin(),v[1].end()); ans=sum; for(ll i=v[0].size()-1;i>=0;i--) sum+=v[0][i]+v[1][i],ans=max(ans,sum); printf("%lldn",ans); }
最后
以上就是有魅力橘子最近收集整理的关于ATcoder-[AGC048B]Bracket Score【结论,贪心】正题的全部内容,更多相关ATcoder-[AGC048B]Bracket内容请搜索靠谱客的其他文章。
发表评论 取消回复