zoukankan      html  css  js  c++  java
  • [高精度][贪心]Luogu P1080 国王游戏

    题目描述

    恰逢 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%的数据,保证答案不超过 10^9;

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

    题解

    • 如果i和j两个相邻那么i排在j前面的必要条件是

    • total*a[i]/b[j]<total*a[j]/b[i]

    • 也就是说 a[i]*b[i]<a[j]*b[j]

    • 而本题中,n<1000,a,b<10000

    • 1000个10000乘起来那肯定存不下

    • 所以要用高精度

    代码

     1 #include<cstdio>
     2 int n,l=1,a[100010],b[100010],c[100010],g[1000010];
     3 void gj1(int x)
     4 {
     5     for(int i=1;i<=l;i++) g[i]*=b[x];
     6     for(int i=1;i<=l;i++)
     7     {
     8         g[i+1]+=(g[i]/10);
     9         g[i]%=10;
    10     }
    11     l++;
    12     while(g[l]>9)
    13     {
    14         g[l+1]+=(g[l]/10);
    15         g[l]%=10;
    16         l++;
    17     }
    18     if(g[l]==0) l--;
    19 }
    20 void gj2()
    21 {
    22     for(int i=l;i>=1;i--)
    23     {
    24         g[i-1]+=((g[i]%c[n])*10);
    25         g[i]/=c[n];
    26     }
    27     while (g[l]==0) l--;
    28     if(l==0) printf("1
    ");
    29 }
    30 void qsort(int l,int r)
    31 {
    32     int i=l,j=r,mid=a[(l+r)/2];
    33     while(i<=j)
    34     {
    35         while(a[i]<mid) i++;
    36         while(a[j]>mid) j--;
    37         if(i<=j)
    38         {
    39             int t=a[i]; a[i]=a[j]; a[j]=t;
    40             t=b[i]; b[i]=b[j]; b[j]=t;
    41             t=c[i]; c[i]=a[j]; c[j]=t;
    42             i++; j--;
    43         }
    44     }
    45     if(l<j) qsort(l,j);
    46     if(i<r) qsort(i,r);
    47 }
    48 int main()
    49 {
    50     scanf("%d",&n);
    51     scanf("%d %d",&b[0],&c[0]);
    52     for(int i=1;i<=n;i++)
    53     {
    54         scanf("%d %d",&b[i],&c[i]);
    55         a[i]=b[i]*c[i];
    56     }
    57     qsort(1,n);
    58     g[1]=b[0];
    59     for(int i=1;i<n;i++) gj1(i);
    60     gj2();
    61     for(int i=l;i>=1;i--) printf("%d",g[i]);
    62     return 0;
    63 }
  • 相关阅读:
    VS2008编写MFC程序--使用opencv2.4()
    November 02nd, 2017 Week 44th Thursday
    November 01st, 2017 Week 44th Wednesday
    October 31st, 2017 Week 44th Tuesday
    October 30th, 2017 Week 44th Monday
    October 29th, 2017 Week 44th Sunday
    October 28th, 2017 Week 43rd Saturday
    October 27th, 2017 Week 43rd Friday
    October 26th, 2017 Week 43rd Thursday
    October 25th, 2017 Week 43rd Wednesday
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8480843.html
Copyright © 2011-2022 走看看