题目描述
牛牛和 牛可乐 面前有 n 个物品,这些物品编号为 1 , 2 , … , n 1,2,\dots,n 1,2,…,n ,每个物品有两个属性 a i , b i a_i, b_i ai,bi。
牛牛与 牛可乐会轮流从剩下物品中任意拿走一个, 牛牛先选取。
设 牛牛选取的物品编号集合为 H,牛可乐选取的物品编号的集合为 T,取完之后,牛牛 得分为 ∑ i ∈ H a i \sum_{i\in H} a_i ∑i∈Hai ;而 牛可乐得分为 ∑ i ∈ T b i \sum_{i\in T} b_i ∑i∈Tbi 。
牛牛和 牛可乐都希望自己的得分尽量比对方大(即最大化自己与对方得分的差)。
你需要求出两人都使用最优策略的情况下,最终分别会选择哪些物品,若有多种答案或输出顺序,输出任意一种。
输入描述:
第一行,一个正整数 n,表示物品个数。
第二行,n 个整数
a
1
,
a
2
,
…
,
a
n
a_1,a_2,\dots,a_n
a1,a2,…,an ,表示 n 个物品的 A 属性。
第三行,n 个整数
b
1
,
b
2
,
…
,
b
n
b_1,b_2,\dots,b_n
b1,b2,…,bn ,表示 n 个物品的 B 属性。
保证
2
≤
n
≤
2
×
1
0
5
,
0
≤
a
i
,
b
i
≤
1
0
9
2\leq n\leq 2\times 10^5 ,0\leq a_i,b_i\leq 10^9
2≤n≤2×105,0≤ai,bi≤109 。
输出描述:
输出两行,分别表示在最优策略下 牛牛和 牛可乐各选择了哪些物品,输出物品编号。
输入
3
8 7 6
5 4 2
输出
1 3
2
说明
3 1
2
也会被判定为正确
题解
-
假设物品已经被选完,此时 牛牛选择的物品 A 属性的价值和是 N , 牛可乐选择的物品 BB 属性价值和是 M 。
-
如果 牛牛的 ( a 1 , b 1 ) (a_1,b_1) (a1,b1) 物品与 牛可乐的 ( a 2 , b 2 ) (a_2,b_2) (a2,b2) 交换,则 N ′ = N − a 1 + a 2 , M ′ = M + b 1 − b 2 N'=N-a_1+a_2, M'=M+b_1-b_2 N′=N−a1+a2,M′=M+b1−b2 ,对于 牛牛(目标是最大化 N − M N-M N−M )来说会变得更优仅当 a 1 + b 1 < a 2 + b 2 a_1+b_1<a_2+b_2 a1+b1<a2+b2 ( N ′ − M ′ > N − M N'-M'>N-M N′−M′>N−M 化简就能得到),对于 牛可乐也一样。所以两人都会优先选择 a i + b i a_i+b_i ai+bi 最大的物品。
-
将物品按照两个属性的和从大到小排序,依次分给两人即可。
-
除排序时间复杂度 O ( n ) O(n) O(n) 。
AC-Code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 7;
struct Node {
int a, b, i;
bool operator < (Node t)const {
return t.a + t.b < a + b;
}
}node[maxn];
int main() {
int n; cin >> n;
for (int i = 0; i < n; ++i) node[i].i = i+1, cin >> node[i].a;
for (int i = 0; i < n; ++i) cin >> node[i].b;
sort(node, node + n);
cout << node[0].i;
for (int i = 2; i < n; i += 2)
cout << " " << node[i].i;
cout << endl << node[1].i;
for (int i = 3; i < n; i += 2)
cout << " " << node[i].i;
cout << endl;
}