题目描述
Hikari 和 Tairitsu 面前有 n 个物品,这些物品编号为 1,2,…,n。
每个物品有两个属性。第 i 个物品的两个属性分别为 ai, bi 。
初始 n 个物品均可被选取。Hikari 与 Tairitsu 会轮流选取当前可选取的物品中的一个,并把它拿走,这个物品之后不可被选取。第一轮 Hikari 先选取。
设 Hikari 选取的物品编号的集合为 H ,Tairitsu 选取的物品编号的集合为 T 。
所有物品均被选取完之后,Hikari 得分为∑ ai(i ∈ H) ;而 Tairitsu 得分为∑ bi(i ∈ T) 。
Hikari 和 Tairitsu 都希望自己的得分比对方大,你需要求出双方都使用最优策略的情况下,双方各会获得多少分。
注意: 若对于某个人来说,剩余的物品中有多个对两人分数大小关系影响相同的物品,那么他会优先选择 bi 最大的那个。
输入一个正整数 n,表示物品个数。
再输入两个数组 a 和 b,分别表示 n 个物品的 A 属性和 n 个物品的 B 属性。(保证 1<=n<=2*1e5, 0<=ai,bi<=1e9)
输出一行,两个整数分别表示 Hikari 和 Tairitsu 的得分。
示例 1
输入:
5
[1,2,3,4,5]
[5,4,3,2,1]
输出:
[9,6]
解题思路:
根据题意,分析得知,Hikari 和 Tairitsu 每次会优先选择 ai+bi 的值最大的物品,当物品的 ai+bi 值相等时,选择 bi 大的那个。
因此,可以对物品进行排序,排序有两个依据,优先依据 ai+bi 的值,然后是 bi的值。降序排好后,Hikari 和 Tairitsu 依次按顺序选择物品,Hikari 先选择,选择好以后,分别计算 Hikari 和 Tairitsu 的分数即可。
/**
* Tairitsu and Dynamic Objects
* @param n 表示物品个数
* @param a n 个物品的 A 属性
* @param b n 个物品的 B 属性
* @return 输出一行,两个整数分别表示 Hikari 和 Tairitsu 的得分
*/
public static long[] solution(int n, int[] a, int[] b){
int[][] m = new int[n][];
for(int i = 0; i < n; i++){
m[i] = new int[2];
m[i][0] = a[i];
m[i][1] = b[i];
}
Arrays.sort(m, new Comparator<int[]>() {
public int compare(int[] o1, int[] o2) {
int a_now = o1[0]+o1[1];
int b_now = o2[0]+o2[1];
if(b_now>a_now){
return 1;
}else if(b_now < a_now){
return -1;
}else if(o2[1]>o1[1]){
return 1;
}else if(o2[1]<o1[1]){
return -1;
}else{
return 0;
}
}
});
long a_score = 0;
long b_score = 0;
for (int i = 0; i < n ; i++){
if(i%2 == 0){
a_score = a_score + m[i][0];
}else{
b_score = b_score + m[i][1];
}
}
long[] ret = new long[2];
ret[0] = a_score;
ret[1] = b_score;
return ret;
}