AtCoder题解——AtCoder Grand Contest 048——B - Bracket Score

题目相关

题目链接

AtCoder Grand Contest 048 B 题,https://atcoder.jp/contests/agc048/tasks/agc048_b

Problem Statement

In this problem, we consider strings consisting of (, ), [, and ]. A string x is said to be a good parentheses sequence if and only if one of the following conditions is satisfied:

  • x is an empty sequence.
  • There is a good parentheses sequence s such that concatenating (, s, and ) in this order results in x.
  • There is a good parentheses sequence s such that concatenating [, s, and ] in this order results in x.
  • There are non-empty good parentheses sequences s and t such that concatenating s and t in this order results in x The score for s.

For example, [], ([()]), and ()[()] are good parentheses sequences, but neither ()) nor ([)] is a good parentheses sequence.

Given are an even number N and integer sequences A and B of length N each. Here, we define a score for a good parentheses sequence of length N, s=s1 s2 ⋯ sN, as follows:

  • is the sum of the scores of its characters.
  • The score for the i-th character (1≤i≤N) is Ai if si is ( or ), and Bi if si is [ or ].

Find the maximum possible score for a good parentheses sequence of length N.

Input

Input is given from Standard Input in the following format:

N
A1 A2 ⋯ AN
B1 B2 ⋯ BN

Output

Print the answer.

Samples1

Sample Input 1

4
4 2 3 1
2 3 2 4

Sample Output 1

12

Explaination

For s=()[], the score is A1+A2+B3+B4=12, which is the maximum possible value.

Samples2

Sample Input 2

10
866111664 844917655 383133839 353498483 472381277 550309930 378371075 304570952 955719384 705445072
178537096 218662351 231371336 865935868 579910117 62731178 681212831 16537461 267238505 318106937

Sample Output 2

6629738472

Constraints

  • 2 ≤ N ≤ 10^5
  • N is an even number.
  • 1 ≤ Ai ≤ 10^9
  • 1 ≤ Bi ≤ 10^9
  • All numbers in input are integers.

题解报告

题目翻译

一个字符串 x 只包含 (, ), [, 和 ],字符串 x 满足以下条件,我们定义为好的圆括号序列:

  • 空串;
  • 一个好的圆括号序列 s,连接 (、s 和 ) 得到字符串 x;
  • 一个好的圆括号序列 s,连接 [、s 和 ] 得到字符串 x;
  • 一个非空,好的圆括号序列 s 和 t,连接起来组成字符串 x。

例如:[], ([()])()[()] 是好的序列; ()) 或者 ([)] 都是不好的序列。

给定一个偶数 N 和两个长度为 N 的整数序列 A 和 B,这里我们定义一个字符串 S 的分数,分数计算规则如下:

  • 分数是字符串的每个字符的分数总和;
  • 如果第 i 个字符是 ( 或者 ),它的分数是 Ai;如果第 i 个字符是 [ 或者 ],它的分数是 Bi。

请找出字符串 S 的最大分数。

题目分析

还是英文的阅读问题,“There are non-empty good parentheses sequences s and t such that concatenating s and t in this order results in x.” 这句话理解了半天。因为这句话开始没理解,一直没想明白为什么 ([)] 不是一个好的序列。哎惭愧。

开始还想用堆栈,后面仔细推敲了一下,这个题目还是一个数学题,和堆栈一点点关系都没有。

假设字符串 S 的长度为 K,同时字符串 S 是一个好的序列,每个字符所在位置为 x_{1}, x_{2}, \cdots , x_{K}。这样可以分为 \frac{K}{2} 个配对,我们假设 (x_{1}, x_{2})(x_{3}, x_{4})、...、(x_{k-1}, x_{k}) 可以配对。对于每一个配对,假设 x_{i}<x_{i+1}

根据题目给出的条件,这样 x_{i}+1 字符和 x_{i+1}-1 字符也是可以配对的。这就意味着 x_{i}x_{i+1} 的奇偶性是不同的。也就意味着这 K 个数中,必须有\frac{K}{2} 个奇数,\frac{K}{2} 个偶数。同时一半奇数,一半偶数是构成好序列的充分条件。我们可以使用构造法来证明。

1、序列 x 本身已经满足好序列条件;

2、我们一定可以找到一个奇数 x_{i} 和一个偶数 x_{j} 满足题目要求;

3、将配对的 x_{i}x_{j} 消去,这个时候,序列 x 还是满足半奇半偶。

4、重复 2 和 3 即可。

这样,原来的问题就转化为从 A 和 B 中找到一个 x_{1}, x_{2}, \cdots , x_{K},满足半奇半偶,而且总和最大。这样,我们假设 ( 和 ) 为选择 0,[ 和 ] 为选择 1,这样就变为选择 \frac{n}{2} 个 0 和 \frac{n}{2} 个 1 使得总和最大。

算法设计

这样,我们可以得到算法的思路如下:

(1)先将偶数位置的 Bi 和 Ai 进行交换;

(2)吧 A 全部选了;

(3)计算 B[i]-A[i],生成新的序列 B,再从小到大排序;

(4)选择新 B 序列的 \frac{n}{2} 个数据。

实现细节

快读

注意数据量(2e5)比较大,需要使用快读。

数组数据范围

A 和 B 最大值为 1e9,过程中会使用到 B[i]-a[i],因此理论上说,使用 int 保存数据是可以的。为了安全起见,我建议使用 long long。

答案数据

A 和 B 最大值为 1e9,N 的最大值为 2e5,那么 ans 的最大可能性应该为:1e5*1e9=1e14,超过了 int 的范围。必须使用 long long。

AC 参考代码

//https://atcoder.jp/contests/agc048/tasks/agc048_b
//B - Bracket Score
#include <bits/stdc++.h>

using namespace std;

const int MAXN=2e5+4;
long long a[MAXN];
long long b[MAXN];

int main() {
    ios::sync_with_stdio(false);

    int n;
    cin>>n;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
    }
    for (int i=1; i<=n; i++) {
        cin>>b[i];
        if (0==i%2) {
            swap(a[i], b[i]);
        }
    }

    long long ans=0;
    for (int i=1; i<=n; i++) {
        ans+=a[i];
        b[i]-=a[i];
    }
    sort(b+1, b+n+1, greater<int>());//降序
    for (int i=1; i<=n/2; i++) {
        ans+=b[i];
    }

    cout<<ans<<"\n";

    return 0;
}

时间复杂度

由于使用了排序,因此本题的时间复杂度为 O(NlogN)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的老周

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值