Tairitsu and Dynamic Objects--算法笔试模拟题精解

题目描述

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;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值