P1080 [NOIP2012 提高组] 国王游戏

179 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情

P1080 [NOIP2012 提高组] 国王游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目:恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。
思路:假设有两个大臣a,b,左手的数为a1,b1,右手a2,b2,前面的大臣们左手的乘积为s,假设a在b前面更优,那么max(s/a2,sa1/b2)<=max(s/b2,sb1/a2),显然sa1/b2>=s/b2,假设sa1/b2=sb1/a2,那么
max(s/a2,s
a1/b2)>=max(s/b2,sb1/a2),就与之前的假设矛盾了,所以sa1/b2<s*b1/a2,即a1/b2<b1/a2,根据这个排个序然后遍历出最大值就可以了

import java.awt.peer.SystemTrayPeer;
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static class ki{
        int l,r;

        public ki() {
        }

        public ki(int l, int r) {
            this.l = l;
            this.r = r;
        }
    }
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int n=in.nextInt(),x=in.nextInt(),y=in.nextInt();
        List<ki> list=new ArrayList<>();
        for(int i=1;i<=n;i++){
            list.add(new ki(in.nextInt(),in.nextInt()));
        }
        Collections.sort(list, new Comparator<ki>() {
            @Override
            public int compare(ki o1, ki o2) {
                //改成*号不易发生除0错误
                return o1.l*o1.r-o2.l*o2.r;
            }
        });
        BigInteger ans=BigInteger.valueOf(0),mul=BigInteger.valueOf(x);
        for(ki k:list){
            BigInteger tmp=mul.divide(BigInteger.valueOf(k.r));
            ans=ans.max(tmp);
            mul=mul.multiply(BigInteger.valueOf(k.l));
        }
        System.out.println(ans);
        in.close();
    }
}