CF725F 做题记录

· · 题解

https://www.luogu.com.cn/problem/CF725F

Problem

n 堆照片,每堆有两张,拿走上面一张才能拿下面的。

Alice 拿走第 i 堆的第 j\in[1,2] 张可以获得 a_{ij} 的积分,Bonnie 则可以获得 b_{ij} 的积分。两人都有权力从一堆中拿走一张或者不拿。

令 Alice 的最终积分为 x,Bonnie 的为 y,求最大的 x-y

Solution

题目要求最大化 x-y,我们考虑 Alice 取了一张 (a,b) 的照片对这个值的贡献。

同理,如果被 Bonnie 拿到,净贡献就是 $-(a+b)$。 既然净贡献都与 $a+b$ 直接相关,$a+b$ 就是这张照片的价值。 再考虑本题的简化情况:假如每堆只有一张照片。 显然无论哪个人每次都会取 $a+b$ 最大的一张照片。把 $a+b$ 丢进大根堆贪心即可。 但是本题中每堆有两张照片,于是我们考虑比较这两张照片的价值。 假设当前堆的两个照片分别为 $(a_1,b_1),(a_2,b_2)$,前者在上,对这俩的价值大小分类讨论。 倘若 $a_1+b_1\ge a_2+b_2$,那肯定不会有人为了第二张照片放弃第一张,此时两张照片相互独立,因为第一张价值更大,必然会被先取,「先取第一张才能取第二张」的依赖关系自然成立。 若 $a_1+b_1<a_2+b_2$,此时第二张更好,我们需要观察最坏的情况:即我方拿走第一张,对方拿走第二张时,是否依然对我方有利。 对 Alice,最坏价值为 $v_A=a_1-b_2$,对 Bonnie 最坏价值为 $v_B=b_1-a_2$。 考虑将这两个价值分别与 $0$ 比较,有四种情况。 1. $v_A\le 0,v_B\le 0$,显然不会有人动。 2. $v_A>0,v_B\le0$,Alice 会拿走第一张,Bonnie 拿走第二张,贡献为 $v_A$。 3. $v_A\le0,v_B>0$,同理,贡献为 $-v_B$。 4. $v_A>0,v_B>0$,这个东西和 $a_1+b_1<a_2+b_2$ 是矛盾的,证明简单。 ### Code 一个不太简洁但十分自然的实现。 :::success[参考实现] ```cpp #include <bits/stdc++.h> #define int long long using namespace std; struct Photo { int a, b; bool operator<(const Photo& other) const { return a + b < other.a + other.b; } }; priority_queue<Photo> pq; signed main() { cin.tie(0) -> sync_with_stdio(0); int n, ans = 0; cin >> n; for (int i = 1; i <= n; i ++) { int a1, b1, a2, b2; cin >> a1 >> b1 >> a2 >> b2; if (a1 + b1 >= a2 + b2) { pq.push({a1, b1}), pq.push({a2, b2}); } else { int vA = a1 - b2, vB = b1 - a2; if (vA > 0 && vB <= 0) ans += vA; else if (vA <= 0 && vB > 0) ans += -vB; } } bool alice_turn = true; while (!pq.empty()) { Photo top = pq.top(); pq.pop(); if (alice_turn) ans += top.a; else ans -= top.b; alice_turn ^= 1; } cout << ans << '\n'; } ``` :::