PTA Birthday Gift (排序+假设减少变量)

7-12 Birthday Gift (20分)

On Derrick’s birthday, Derrick received a gift from his girlfriend Sandy. The gift consists n tiny balls, and each of them has two characteristics a and b. As Derrick is boring, he just wants to play with these balls.

Each time Derrick chooses two balls randomly. For each pair of balls x, y, Derrick defines their beautiful value as min(X​a + Yb, Xb + Ya).

Given the properties a and b of all the n tiny balls, Derrick will select exactly two of them and maximum their beautiful value. Now he needs your help, please help him.

Input Specification:

Each input file only contains one test case.

The first line contains an integer n (2 ≤ n ≤ 2×10
​5​​ ), indicating the total number of the tiny balls.

The second line contains n integers a
​1​​ ,a​2​​ ,…,a​n​​ (1 ≤ a​i​ ≤ 10​9​​ ), indicating the characteristic a of each ball.

The third line contains n integers b​1​​ ,b​2​​ ,…,b​n​​ (1 ≤ b​i​​ ≤ 10​9​ ), indicating the characteristic b of each ball.

Output Specification:

For each test case, output a single integer in a line indicating the maximum beautiful value of the given tiny balls.

Sample Input:

5
1 3 5 4 2
2 4 3 5 3

Sample Output:

8

解题

感谢大佬思路:https://blog.csdn.net/weixin_45750972/article/details/106547534

  1. 先分析题意,如果用暴力解法,每一个小球都要与其它小球比较,现在先将题目改为求第一个球(x球)与其它n - 1 个球(y球)得最优值,显然他与每个球构成的值为min(xa + yb, xb + ya), 也就是有两种可能,即x球选了a性质,或x球选了b性质,那么现在做的就是将两种选择转换为一种选择,于是借助大佬的思路。
  2. 对于min(xa + yb, xb + ya),现在假设选了x,y两球比较,把第一个球a性质 + 另一个球b性质小的结果中(两者取min的结果),我们总是第一个球称作x球,第二个球称作y球,于是做出以下假定:
    对任意的x,y球都满足xa + yb <= xb + ya(如果不满足就把X、Y球交换使其满足,这里只是表示这种假定能成立);
    那么由(xa + yb <= xb + ya) => (xa - xb <= ya - yb),现在对小球以该形式进行排序,也就是每个在前面的小球与后面的小球都满足,前面的小球为X球后面的小球为Y球,即都有
    xa + yb <= xb + ya , 恒成立
    再从前往后遍历,每遍历到该球(X球)时,都计算出该球后面的最大的Yb即为该球与后面的组成的最优解,然后取最大值就是所有球的最优解。
  3. 用rk[i]数组表示从i开始后面的最大的Yb

代码

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
const int maxn = 2e5 + 2;
// int a[maxn], b[maxn];
int rk[maxn];

struct node {
    int a, b;
} ball[maxn];

bool cmp(const node &x, const node &y) { return x.a - x.b < y.a - y.b; }

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &ball[i].a);
    }
    for (int i = 1; i <= n; i++) {
        scanf("%d", &ball[i].b);
    }
    sort(ball + 1, ball + n + 1, cmp);
    // for (int i = 1; i <= n; i++) {
    //     cout << ball[i].a << " " << ball[i].b << endl;
    // }

    for (int i = n; i >= 1; i--) {
        rk[i] = max(rk[i + 1], ball[i].b);  // rk[i], 从下标i开始后面最大的y.b
    }

    // 相当于把每对小球之间的比较有两种情况,全部转换为一种情况了
    int ans = 0;
    for (int i = 1; i < n; i++) {
        ans = max(ans, rk[i + 1] + ball[i].a);
    }
    cout << ans << endl;

    system("pause");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值