题目描述
牛牛和牛可乐面前有个物品,这些物品编号是,,……,每个物品有两个属性,。
牛牛和牛可乐会轮流从剩下的物品任意拿走一个,牛牛先选。
设牛牛选取的物品编号集合为H,牛可乐选取的物品编号的集合为T,取完之后,牛牛得分为 ,而 牛可乐得分为。
牛牛和 牛可乐都希望自己的得分尽量比对方大(即最大化自己与对方得分的差)。
你需要求出两人都使用最优策略的情况下,最终分别会选择哪些物品,若有多种答案或输出顺序,输出任意一种。
思路
首先假设个物品已被选完,且牛牛总得分为,牛可乐总分为,如果两人交换一对物品,这两个物品属性分别为 ,设被牛牛选走了,那么交换后两人总得分分别为牛牛:,牛可乐:,我们要最大化的值,那么交换后的差值可以表示为:,合并后得:,如果,那么交换后就会更大化两个人得分差值,也就是说影响差值的是同一个物品的两个属性之和,根据两个物品属性之和排序,然后依次从大到小选就可以了
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
struct p{
ll a, b, c;
int index;
p(){
}
p(ll a, ll b){
this->a = a;
this->b = b;
}
};
bool cmp(p& a, p& b){
return a.c > b.c;
}
p arr[N];
int n;
vector<int> t1, t2;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)cin >> arr[i].a;
for (int i = 1; i <= n; i++)cin >> arr[i].b;
for (int i = 1; i <= n; i++)arr[i].index = i;
for (int i = 1; i <= n; i++)arr[i].c = arr[i].b + arr[i].a;
sort(arr + 1, arr + 1 + n, cmp);
bool f = 1;
for (int i = 1; i <= n; i++){
(f ? t1 : t2).push_back(arr[i].index);
f = !f;
}
for (int i : t1){
cout << i << " ";
}
printf("\n");
for (int i : t2){
cout << i << " ";
}
return 0;
}