我是靠谱客的博主 有魅力橘子,最近开发中收集的这篇文章主要介绍ATcoder-[AGC048B]Bracket Score【结论,贪心】正题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

正题

题目链接: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=aibi的价值。然后每次选取一奇一偶的 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

#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 Score【结论,贪心】正题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部