• 【NOIP 2012 国王游戏】 贪心+高精度


    题目描述

    恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右

    手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排

    成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每

    位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右

    手上的数,然后向下取整得到的结果。

    国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,

    使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

    输入输出格式

    输入格式:

    第一行包含一个整数 n,表示大臣的人数。

    第二行包含两个整数 a和 b,之间用一个空格隔开,分别表示国王左手和右手上的整数。

    接下来 n 行,每行包含两个整数 a 和 b,之间用一个空格隔开,分别表示每个大臣左手

    和右手上的整数。

    输出格式:

    输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的

    金币数。

    输入输出样例

    输入样例#1:
    3 
    1 1 
    2 3 
    7 4 
    4 6 
    输出样例#1:
    2

    说明

    【输入输出样例说明】

    按 1、2、3 号大臣这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

    按 1、3、2 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

    按 2、1、3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

    按 2、3、1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9;

    按 3、1、2 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

    按 3、2、1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9。

    因此,奖赏最多的大臣最少获得 2 个金币,答案输出 2。

    【数据范围】

    对于 20%的数据,有 1≤ n≤ 10,0 < a、b < 8;

    对于 40%的数据,有 1≤ n≤20,0 < a、b < 8;

    对于 60%的数据,有 1≤ n≤100;

    对于 60%的数据,保证答案不超过 109;

    对于 100%的数据,有 1 ≤ n ≤1,000,0 < a、b < 10000。

    NOIP 2012 提高组 第一天 第二题

     

    我要直接搬运证明了。。

    按照a*b排序,然后计算,计算那里要高精度。

     

    国王游戏

    将左手与右手的乘积从小到大排序,然后计算求最大值即可。(需要高精度)

    证明:

    1)知道,如果相邻的两个人交换位置,只会影响到这两个人的值,不会影响他人

    2)假设相邻的两个人i, i + 1。设A[i] B[i] <= A[i + 1] B[i + 1],i之前所有人的左手乘积为S。

    则,ans1 = max{S / B[i], S * A[i] / B[i + 1]}

    若交换

    则,ans2 = max{S / B[i + 1], S * A[i + 1] / B[i]}

    因为,A[i] B[i] <= A[i + 1] B[i + 1]

    所以,S A[i] / B[i + 1] <= S A[i + 1] / B[i]

    又因为,S / B[i + 1] <= S * A[i] / B[i + 1]

    所以,ans2 = S * A[i + 1] / B[i]

    ans1 = max{S / B[i], S * A[i] / B[i + 1]}

    所以,ans1 <= ans2

    证毕 至于高精度:

    由题意知,0 < a,b < 10000,所以用10000进制的高精度进行运算就可以了

    转自 新浪博客

    链接

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<cmath>
     8 using namespace std;
     9 #define Maxn 1010
    10 
    11 struct node
    12 {
    13     int a,b;
    14 }t[Maxn];
    15 
    16 bool cmp(node x,node y) {return x.a*x.b<y.a*y.b;}
    17 
    18 struct bint
    19 {
    20     int w[30010],l;
    21 };
    22 bint now,mx,C;
    23 
    24 void mul(int x)
    25 {
    26     for(int i=1;i<=now.l;i++) now.w[i]*=x;
    27     for(int i=1;i<=now.l;i++)
    28     {
    29         now.w[i+1]+=now.w[i]/10;
    30         now.w[i]%=10;
    31     }
    32     while(now.w[now.l+1]!=0)
    33     {
    34         now.w[now.l+2]+=now.w[now.l+1]/10;
    35         now.w[now.l+1]%=10;
    36         now.l++;
    37     }
    38 }
    39 
    40 void get_C(int x)
    41 {
    42     int y=0;
    43     C.l=now.l;
    44     memset(C.w,0,sizeof(C.w));
    45     for(int i=now.l;i>=1;i--)
    46     {
    47         y=y*10+now.w[i];
    48         if(y>=x)
    49         {
    50             C.w[i]=y/x;
    51             y%=x;
    52         }
    53     }
    54     while(C.w[C.l]==0&&C.l>1) C.l--;
    55 }
    56 
    57 void change()
    58 {
    59     mx.l=C.l;
    60     for(int i=1;i<=C.l;i++) mx.w[i]=C.w[i];
    61 }
    62 
    63 void get_mx()
    64 {
    65     if(C.l<mx.l) return;
    66     else if(C.l>mx.l) change();
    67     else
    68     {
    69         for(int i=C.l;i>=1;i--)
    70         {
    71             if(C.w[i]<mx.w[i]) return;
    72             if(C.w[i]>mx.w[i]) {change();return;}
    73         }
    74     }
    75 }
    76 
    77 int main()
    78 {
    79     int n;
    80     scanf("%d",&n);
    81     int A,B;
    82     scanf("%d%d",&A,&B);
    83     for(int i=1;i<=n;i++) scanf("%d%d",&t[i].a,&t[i].b);
    84     sort(t+1,t+1+n,cmp);
    85     now.l=1;memset(now.w,0,sizeof(now.w));
    86     now.w[1]=1;
    87     mx.l=1,mx.w[1]=0;
    88     
    89     mul(A);
    90     for(int i=1;i<=n;i++)
    91     {
    92         get_C(t[i].b);
    93         get_mx();
    94         mul(t[i].a);
    95     }
    96     for(int i=mx.l;i>=1;i--) printf("%d",mx.w[i]);
    97     printf("
    ");
    98     return 0;
    99 }
    View Code

    2016-11-16 10:32:55

  • 相关阅读:
    了解 DICOM 基本协议与其相关
    C# PropertyInfo 反射实体部分字段
    ref(引用参数) 和 out(输出参数) 区别
    Linq Where Expression<Func<T,bool>> 查询条件
    随笔规范
    C# 集合分析
    C# 几种常用的数据类型
    关于 C# 方法参数的理解
    打算开始写博客了
    有趣的算法、逻辑面试题
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6068498.html
Copyright © 2020-2023  润新知