题目描述
牛牛和 牛可乐 面前有 n 个物品,这些物品编号为 ,每个物品有两个属性 。
牛牛与 牛可乐会轮流从剩下物品中任意拿走一个, 牛牛先选取。
设 牛牛选取的物品编号集合为 H,牛可乐选取的物品编号的集合为 T,取完之后,牛牛 得分为 ;而 牛可乐得分为 。
牛牛和 牛可乐都希望自己的得分尽量比对方大(即最大化自己与对方得分的差)。
你需要求出两人都使用最优策略的情况下,最终分别会选择哪些物品,若有多种答案或输出顺序,输出任意一种。
输入描述:
第一行,一个正整数 n,表示物品个数。
第二行,n 个整数
,表示 n 个物品的 A 属性。
第三行,n 个整数
,表示 n 个物品的 B 属性。
保证
。
输出描述:
输出两行,分别表示在最优策略下 牛牛和 牛可乐各选择了哪些物品,输出物品编号。
输入
3
8 7 6
5 4 2
输出
1 3
2
说明
3 1
2
也会被判定为正确
题解
-
假设物品已经被选完,此时 牛牛选择的物品 A 属性的价值和是 N , 牛可乐选择的物品 BB 属性价值和是 M 。
-
如果 牛牛的 物品与 牛可乐的 交换,则 ,对于 牛牛(目标是最大化 )来说会变得更优仅当 ( 化简就能得到),对于 牛可乐也一样。所以两人都会优先选择 最大的物品。
-
将物品按照两个属性的和从大到小排序,依次分给两人即可。
-
除排序时间复杂度 。
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;
}