zoukankan      html  css  js  c++  java
  • 洛谷P1080 国王游戏【大数】【贪心】

    题目https://www.luogu.org/problemnew/show/P1080

    题意:

    一个国王和n个大臣,每个人左右手上都有一个数值。

    现在将国王排在队首,将大臣进行排序。每个大臣的值是他前面所有人的左手值的积除以他自己右手的值。

    问怎样的排序可以使得大臣的值中的最大值尽可能的小。

    思路:

    看题目感觉会是一个排序的问题,但是刚开始没想出来拿什么当关键字。

    后来看了题解。感觉这种题目的关键是先考虑只有两个对象,分别计算这两个对象一前一后得到的答案,然后根据答案的不等式推出应该以什么作为关键字比较两个对象。

    因此我们考虑一个大臣左右手的数值是a1,b1,另一个大臣走右手数值是a2,b2,国王的左右手数值是a0,b0

    当1在前2在后时,可以得到$k1=a0/b1$和$k2=a0*a1/b2$,设此时答案是ans1

    当2在前1在后时,可以得到$k3=a0/b2$和$k4=a0*a2/b1$,设此时答案是ans2

    可以发现$k3<k2,k4>k1$

    如果$ans1<ans2$恒成立也就是说我们要选择1在前2在后的情况,即$max(k1,k2)<max(k3,k4)$,那么$k4>k2$且$k4>k3$,此时$a2*b2>a1*b1$

    这说明了左右手之积较小的应该放在前面。

    推出了排序的规则,接下来就比较简单了。要注意的是这道题用到了大数。

     1 import java.lang.reflect.Array;
     2 import java.math.BigInteger;
     3 import java.util.Arrays;
     4 import java.util.BitSet;
     5 import java.util.Comparator;
     6 import java.util.Scanner;
     7 
     8 public class Main {
     9     private static class node{
    10         int lft;
    11         int rgt;
    12     }
    13     final static int maxn = 1005;
    14     static node[] peo;
    15     static Scanner scan = new Scanner(System.in);
    16     static int n;
    17 
    18     private static class cmp implements Comparator<node> {
    19         @Override
    20         public int compare(node a, node b){
    21             if(a.lft * a.rgt < b.lft * b.rgt)return -1;
    22             else if(a.lft * a.rgt == b.lft * b.rgt)return 0;
    23             else return 1;
    24         }
    25     }
    26     public static void main(String[] args){
    27         n = scan.nextInt();
    28         peo = new node[n + 1];
    29         peo[0] = new node();
    30         peo[0].lft = scan.nextInt();
    31         peo[0].rgt = scan.nextInt();
    32         for(int i = 1; i <= n; i++){
    33             peo[i] = new node();
    34             peo[i].lft = scan.nextInt();
    35             peo[i].rgt = scan.nextInt();
    36         }
    37         Arrays.sort(peo, 1, n + 1, new cmp());
    38 
    39         BigInteger res = BigInteger.valueOf(peo[0].lft);
    40         BigInteger ans = BigInteger.ZERO;
    41         for(int i = 1; i <= n; i++){
    42             ans = ans.max(res.divide(BigInteger.valueOf(peo[i].rgt)));
    43             res = res.multiply(BigInteger.valueOf(peo[i].lft));
    44         }
    45 
    46         System.out.println(ans);
    47     }
    48 }
  • 相关阅读:
    别让代码执行不必要的路径和让数据绑定执行了多次
    使用Excel学习英语单词
    如何通过访问记录改善网站质量
    Vs.net2005强势功能:数据源
    新产品:英语单词查找返回表格式结果
    为什么Cpu不能以100%运行 [不完全版]
    乐透彩票研究分析系统
    集成电路发明者杰克·基尔比 IC Inventor Jack Kilby
    ZigBee技术及其应用
    Unix传奇(上篇)
  • 原文地址:https://www.cnblogs.com/wyboooo/p/10872708.html
Copyright © 2011-2022 走看看