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;
    }
    
  • 相关阅读:
    fedora中使用 mariadb数据库建库和建表-- mariadb数据库服务无法启动?
    我在linux中使用的vundle 和 vimrc配置
    vim的加密和解密?
    gvim写html代码时如何快速地跳转到一个标签的结束位置: 终极插件: matchit.vim
    HTML5+CSS3整体回顾
    HTML5无刷新修改URL
    使用ab对nginx进行压力测试
    nginx php-fpm 输出php错误日志
    如何正确配置Nginx+PHP
    关于Nginx的一些优化(突破十万并发)
  • 原文地址:https://www.cnblogs.com/stoorz/p/14215132.html
Copyright © 2011-2022 走看看