zoukankan      html  css  js  c++  java
  • 【AGC048B】Bracket Score

    题目

    题目链接:https://atcoder.jp/contests/agc048/tasks/agc048_b
    一个合法括号序列是包括小括号和中括号的。
    给定长度为 (n) 的数组 (a)(b),一个长度为 (n) 的括号序列的权值为每个字符的权值之和,对于第 (i) 个字符,当其为 () 时,权值为 (a_i);当其为 [] 时,权值为 (b_i)。问一个长度为 (n) 括号序列的权值最大为多少。
    (nleq 10^5,a,bleq 10^9)(n) 是偶数。

    思路

    容易发现一对括号所在位置一定是一奇一偶,所以最终合法括号序列的小括号在奇数位置上的数量和在偶数位置上的数量相同。中括号同理。
    可以证明如果小括号和中括号都满足在奇数位置上的数量与在偶数位置上的数量相同,那么必然存在一组这样的合法括号序列。
    具体的,假设小括号数量大于中括号数量,那么必然存在一对相邻的小括号,删去这一对小括号后转化为子问题。
    如果小括号数量等于中括号数量,为了防止出现连续两个位置填入同一括号,一定是 ([([ 这样排列,但是这样最中间两个括号一定是相同的。删去之后也可以形成一个子问题。
    简单归纳一下即可。
    所以我们只需要在满足两种括号在奇偶位置上数量分别相同即可。所以我们把奇偶位置分开,按照 (a-b) 排序,然后贪心选取即可。
    时间复杂度 (O(nlog n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=100010;
    int n;
    ll ans;
    
    struct node
    {
    	int a,b;
    }a[2][N];
    
    bool cmp(node x,node y)
    {
    	return x.a-x.b>y.a-y.b;
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    		scanf("%d",&a[i&1][(i+1)/2].a);
    	for (int i=1;i<=n;i++)
    		scanf("%d",&a[i&1][(i+1)/2].b);
    	sort(a[0]+1,a[0]+1+n/2,cmp);
    	sort(a[1]+1,a[1]+1+n/2,cmp);
    	for (int i=1;i<=n;i++)
    		ans+=max(a[0][i].a+a[1][i].a,a[0][i].b+a[1][i].b);
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    POSTMAN使用教程
    RocketMQ搭建-WEB集成RMQ-SE集成RMQ
    android studio 低版本升级高版本的问题
    SqlServer 2015修改表时出现“save changes is not permitted…”的解决方法
    MATLAB
    新的学习,加油!
    BAK文件怎么恢复到数据库中
    Go语言基础之包
    Go语言基础之文件操作
    python获取多线程的返回值
  • 原文地址:https://www.cnblogs.com/stoorz/p/14215132.html
Copyright © 2011-2022 走看看