国王游戏(贪心)
题目描述
恰逢 HH H国国庆,国王邀请n nn 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 nnn 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。
输入输出格式
输入格式:
第一行包含一个整数n nn,表示大臣的人数。
第二行包含两个整数 aaa和 bbb,之间用一个空格隔开,分别表示国王左手和右手上的整数。
接下来 nn n行,每行包含两个整数a aa 和 bbb,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。
输出格式:
一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。
输入输出样例
说明
【输入输出样例说明】
按1 11、222、333 这样排列队伍,获得奖赏最多的大臣所获得金币数为 222;
按 111、333、222 这样排列队伍,获得奖赏最多的大臣所获得金币数为2 22;
按 222、111、333 这样排列队伍,获得奖赏最多的大臣所获得金币数为 222;
按2 22、333、11 1这样排列队伍,获得奖赏最多的大臣所获得金币数为9 99;
按 333、111、22 2这样排列队伍,获得奖赏最多的大臣所获得金币数为 222;
按3 33、222、111 这样排列队伍,获得奖赏最多的大臣所获得金币数为 999。
因此,奖赏最多的大臣最少获得 22 2个金币,答案输出 222。
【数据范围】
对于 20%的数据,有 1≤n≤10,0<a,b<81≤ n≤ 10,0 < a,b < 81≤n≤10,0<a,b<8;
对于 40%的数据,有1≤n≤20,0<a,b<8 1≤ n≤20,0 < a,b < 81≤n≤20,0<a,b<8;
对于 60%的数据,有 1≤n≤1001≤ n≤1001≤n≤100;
对于 60%的数据,保证答案不超过 10910^9109;
对于 100%的数据,有 1≤n≤1,000,0<a,b<100001 ≤ n ≤1,000,0 < a,b < 100001≤n≤1,000,0<a,b<10000。
NOIP 2012 提高组 第一天 第二题
思路:既然改变大臣位置可以改变它的结果,我们可以尝试改变位置,
令A【i】表示第i个大臣左手,B【i】表示第i个大臣右手,(i== 0时,为国王)
那么before: max(∏A【i-1】/B【i】,∏A【i】/B【i+1】),after:max(∏A【i-1】*A【i+1】/B【i】,∏A【i-1】/B【i+1】)
显然 ∏A【i】/B【i+1】 > ∏A【i-1】/B【i+1】 且 ∏A【i-1】*A【i+1】/B【i】 > ∏A【i-1】/B【i】
那么只需比较∏A【i】/B【i+1】和 ∏A【i-1】*A【i+1】/B【i】
将其分母、,∏A【i-1】去掉 ,A【i】*B【i】和 A【i+1】*B【i+1】,这就是两个大臣左右手乘积之比
也就是说,如果A【i】*B【i】 < A【i+1】*B【i+1】,那么 before < after
这是相邻大臣之间的,但是我们可以知道,任意两个大臣都可以通过交换相邻大臣从而完成交换(冒泡排序?),这样当以乘积升序排列时就是最优
偷懒用java写
1 import java.util.*; 2 import java.math.*; 3 4 import java.math.BigInteger; 5 6 class peo { 7 int a; 8 int b; 9 public peo() { 10 super(); 11 this.a = a; 12 this.b = b; 13 } 14 } 15 class cmp implements Comparator<peo> { 16 public int compare(peo a, peo b) { 17 if (a.a * a.b < b.a * b.b) { 18 return -1; 19 } else if (a.a * a.b == b.a * b.b) { 20 return 0; 21 } else 22 return 1; 23 } 24 } 25 public class Main { 26 public static void main(String[] args) { 27 Scanner cin = new Scanner(System.in); 28 int n = cin.nextInt(); 29 peo mini[] = new peo[n+1]; 30 for (int i = 0; i <= n; i++) { 31 mini[i] = new peo(); 32 mini[i].a = cin.nextInt(); 33 mini[i].b = cin.nextInt(); 34 } 35 BigInteger ans = BigInteger.ZERO; 36 Arrays.sort(mini, 1, n+1, new cmp()); 37 BigInteger num = BigInteger.ONE; 38 for(int i=1;i<=n;i++) 39 { 40 num = num.multiply(BigInteger.valueOf(mini[i-1].a)); 41 if(num.divide(BigInteger.valueOf(mini[i].b)).compareTo(ans) > 0) 42 { 43 ans = num.divide(BigInteger.valueOf(mini[i].b)); 44 } 45 } 46 System.out.println(ans); 47 } 48 }