zoukankan      html  css  js  c++  java
  • 【乘积排序】 国王游戏

    传送门

    题意

    国王有两个数,每个大臣有两个数,国王始终站在队伍的最前面,每个大臣获得的奖励是他前面所有人左手上的乘积除以他右手上的数,请安排大臣的顺序,使得奖励最大的大臣获得的奖励最小

    数据范围

    (1leq nleq 10000)
    (1leq a,b leq 10000)

    题解

    贪心策略:
    直接将所有大臣按左右手上的数的乘积从小到大排序,得到的序列就是最优排队方案。
    贪心证明:邻项交换
    假设按照乘积升序排列的序列中第(i)和第(i+1)项的奖励分别为 (frac {prod_{j=1}^{i-1} a_{j}}{b_{i}} ,frac {prod_{j=1}^{i} a_{j}}{b_{i+1}})
    交换后的奖励分别为(frac {prod_{j=1}^{i-1} a_{j}}{b_{i+1}} ,frac {prod_{j=1}^{i-1} a_{j}·a_{i+1}}{b_{i}})
    去掉重复项(frac {prod_{j=1}^{i-1} a_{j}}{b_{i}})后,

    • 交换前:(frac{1}{b_{i}} , frac{a_{i}}{b_{i+1}})
    • 交换后:$frac{1}{b_{i+1}} , frac{a_{i+1}}{b_{i}} $

    易知:

    • $ frac{a_{i+1}}{b_{i}} > frac{1}{b_{i}}$
    • (frac{a_{i}}{b_{i+1}} > frac{1}{b_{i+1}})

    所以只需要比较(frac{a_{i+1}}{b_[i]})(frac{a_{i}}{b_{i+1}})的大小即可
    (frac{a_{i+1}}{b_[i]} > frac{a_{i}}{b_{i+1}})
    可以得到
    (a_{i+1} b_{i+1} > a_{i} b_{i})
    所以乘积小的得到的结果更小

    Code

    import java.util.*;
    import java.math.BigInteger;
    import java.math.BigDecimal;
    import java.util.Arrays;
    import java.util.Comparator;
    
    class ele{
    	int left;
    	int right;
    
    	public ele(int left,int right){
    		this.left=left;
    		this.right=right;
    	}
    	public int getleft(){
    		return this.left;
    	}
    	public int getright(){
    		return this.right;
    	}
    }
    public class Main{
    	Scanner sc=new Scanner(System.in);
    	int n;
    	ele e[];
    
    	public void input(){
    		n = sc.nextInt();
    		e = new ele[n+10];
    		for(int i=0;i<=n;i++){
    			e[i]=new ele(sc.nextInt(),sc.nextInt());
    		}
    	}
    
    	public void cal(){
    		Arrays.sort(e,1,n+1,new Comparator<ele>(){
    			public int compare(ele a,ele b){
    				return (a.getleft() * a.getright() - b.getleft() * b.getright());
    			}
    		});
    	
    		BigInteger pre = new BigInteger(String.valueOf(e[0].getleft()));
    		BigInteger mx = BigInteger.ZERO;
    
    		for(int i=1;i<=n;i++){
    			if(pre.compareTo(new BigInteger(String.valueOf(e[i].getright()))) < 0){
    				if(new BigInteger("1").compareTo(mx) > 0){
    					mx = new BigInteger("0");
    				}
    			}
    			else{
    				BigInteger tmp = pre.divide(new BigInteger(String.valueOf(e[i].getright())));
    				if(tmp.compareTo(mx) > 0){
    					mx=tmp;
    				}
    			}
    			pre=pre.multiply(new BigInteger(String.valueOf(e[i].getleft())));
    		}
    		System.out.println(mx);
    	}
    
    
    	public static void main(String[] args){
            Main solve = new Main();
            solve.input();
            solve.cal();
    	}
    }
    
  • 相关阅读:
    高燕师姐博客
    2015.1.12
    功能连接分析论文
    半结构化面试
    各大银行
    独立思考者模型:用专家的思维思考问题
    独立思考者模型:避开思维误区的沼泽
    独立思考者模型:寻找潜藏在表象背后的真相
    独立思考者模型:如何分辨信息的真伪
    独立思考者模型:你相信灵魂转世假说吗?
  • 原文地址:https://www.cnblogs.com/hhyx/p/13167257.html
Copyright © 2011-2022 走看看