zoukankan      html  css  js  c++  java
  • 【NOIP2012】国王游戏

    本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1080


    这道题用到了贪心的思想,与简单的贪心不同,最优解并不能一眼就看出来,需要通过列式比较。我们设想对于任意的两位大臣x和y,他们两个的排列顺序会对答案有影响。假设国王和之前的大臣左手上的数乘积为pre,若x排在y前,ans1=max(pre/x.b,pre*x.a/y.b),ans2=max(pre/y.b,pre*y.a/x.b)。因为必有pre*x.a/y.b>pre/y.b,pre*y.a/x.b>pre/x.b,若要ans1<ans2,则pre*x.a/y.b<pre*y.a/x.b,否则pre*x.a/y.b将会成为最大的数,也就是ans1大于ans2,而我们最终希望答案越小越好,所以就按a*b作为优先级将大臣们排序,最终可以使得获得奖赏最多的大臣所获金币数最小。这是本题的关键,也是一种非常重要的贪心思想,在那道烹调方案中,就要用到。

    有了以上分析就可以有60分,但本题ans的最大值可以达到10^5000左右!!!要用高精度,这才是最坑的。弄了好久才过去,借着这个契机,好好改改我的高精度模板。。。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<string>
     5 using namespace std;
     6 const int maxn=1005,maxl=5005;
     7 int n,ka,kb;
     8 struct BigInteger {
     9     int num[maxl],len;
    10     BigInteger(int x=0) {
    11         memset(num,0,sizeof(num));
    12         num[1]=x;len=1;
    13     }
    14     bool operator < (const BigInteger& rhs) const {
    15         if(len==rhs.len) { //小于运算符可将其他比较运算符表示出来
    16             for(int i=len;i>=1;--i)
    17                 if(num[i]!=rhs.num[i]) return num[i]<rhs.num[i];
    18             return false;
    19         }
    20         else return len<rhs.len;
    21     }
    22      void operator * (const int& rhs) { //高精乘低精
    23         for(int i=1;i<=len;++i) num[i]*=rhs; //先每位乘上再处理进位
    24         for(int i=1;i<=len;++i)
    25             for(int j=i;num[j]>9;++j) {
    26                 num[j+1]+=num[j]/10;
    27                 num[j]%=10;
    28             }
    29         len+=15;
    30         while(!num[len]&&len>1) --len;
    31     }
    32     BigInteger operator / (const int& rhs) const {
    33         BigInteger ans=*this;
    34         for(int i=ans.len;i>=1;--i) {
    35             ans.num[i-1]+=ans.num[i]%rhs*10;
    36             ans.num[i]/=rhs;
    37         }
    38         while(!ans.num[ans.len]&&ans.len>1) --ans.len;
    39         return ans;
    40     }
    41     void print() {
    42         for(int i=len;i>=1;--i) printf("%d",num[i]);
    43     }
    44 } now,ans;
    45 struct minister {
    46     int a,b;
    47     bool operator < (const minister& rhs) const {
    48         return a*b<rhs.a*rhs.b;
    49     }
    50 } M[maxn];
    51 int main() {
    52     scanf("%d%d%d",&n,&ka,&kb);
    53     for(int i=1;i<=n;++i) scanf("%d%d",&M[i].a,&M[i].b);
    54     sort(M+1,M+n+1);
    55     now=BigInteger(1);now*ka;
    56     for(int i=1;i<=n;++i) {
    57         if(ans<now/M[i].b) ans=now/M[i].b;
    58         now*M[i].a;
    59     }
    60     ans.print();
    61     return 0;
    62 }
    AC代码
  • 相关阅读:
    10 期末大作业
    09 spark连接mysql数据库
    08 学生课程分数的Spark SQL分析
    07 从RDD创建DataFrame
    06 Spark SQL 及其DataFrame的基本操作
    05 RDD编程
    05 RDD练习:词频统计
    04 RDD编程练习
    Spark RDD编程
    Spark架构与运行流程
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9626770.html
Copyright © 2011-2022 走看看