zoukankan      html  css  js  c++  java
  • log P1080国王游戏

    洛谷普及训练场贪心的最后一题

    思想上确实是贪心但因为数据范围的问题我80%的时间都是在写高精(魔鬼)

    本题的贪心策略的求解过程几乎是纯数学推导,但一旦把握了这个方向想推出来还是比较容易的,接下来只要耐心把排序和高精写好就可以了

    那么来说一下推导过程:

    首先是本题的无后效性:每个大臣得到的金币数并不会影响后续大臣得到的金币数,因为每位大臣得到的金币数都取决于自己右手的金币数。

    确定这一点之后,不妨让我们请出队尾的两名大臣叶光迪和程驰(程驰为最后),他们左右手上的数字分别是x1,y1和x2,y2。

    来分类讨论看看他们是如何走位排序来满足贪心国王的企图:

        假设前面所有大臣左手数字总和为w

    1.叶光迪在程驰前面时,他得到的金币数为 w/y1 ,而程驰得到的金币数为 w*x1/y2 。因此最多金币数gold1即为两式中较大的一项

    2.程驰在叶光迪前面时,同理,最多金币数gold2为 w/y2 和w*x2/y1 中较大的一项

    由题意得,既然叶光迪在程驰前面,那么说明gold1一定小于gold2,不然不会这么排序

    本题最难理解的地方来了:若gold1<gold2,我们就可以得到 w*x1/y2<w*x2/y1 ,进而x1y1<x2y2

    为什么呢? 进行一下数学推导:1.w*x2/y1>w/y1   w*x1/y2>w/y2

                                                2.gold1和gold2不可能分别等于w/y1和w/y2(不符题意,自行证明)

                                                3.当gold1=w/y1(w/y1>w*x1/y2) w/y2<w*x2/y1 所以w*x1/y2<w*x2/yi

    这样,我们很愉快地得出了贪心策略:将左右手乘积小的大臣排在前面

    感谢叶光迪和程驰大臣

     1 #include<cstdio>
     2 #include<iostream>
     3 int n,l=1,a[100010],b[100010],c[100010];
     4 int g[1000010];
     5 void cheng(int x),chu(),sort(int l,int r);
     6 int main()
     7 {
     8     scanf("%d %d %d",&n,&b[0],&c[0]);
     9     for(int i=0;i<n;i++)
    10     {
    11         scanf("%d %d",&b[i],&c[i]);
    12         a[i]=b[i]*c[i];
    13     }
    14     g[1]=b[0]; 
    15     for(int i=1;i<n;i++) 
    16     cheng(i); chu();
    17     for(int i=l;i>=1;i--) printf("%d",g[i]);
    18     return 0;
    19 }
    20 
    21 void chu(){
    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 
    31 void cheng(int x){
    32     for(int i=1;i<=l;i++) 
    33     g[i]*=b[x];
    34     for(int i=1;i<=l;i++)
    35     {
    36         g[i+1]+=(g[i]/10);
    37         g[i]%=10;
    38     }
    39     l++;
    40     while(g[l]>9)
    41     {
    42         g[l+1]+=(g[l]/10);
    43         g[l]%=10;
    44         l++;
    45     }
    46     if(g[l]==0) l--;
    47 }
    48 
    49 void sort(int l,int r)
    50 {
    51     int le=l,ri=r,mid=a[(l+r)/2];
    52     while(le<=ri)
    53     {
    54         while(a[le]<mid) 
    55         le++;
    56         while(a[ri]>mid) 
    57         ri--;
    58         if(le<=ri)
    59         {
    60             int t=a[le]; 
    61             a[le]=a[ri]; 
    62             a[ri]=t;
    63             
    64             t=b[le]; 
    65             b[le]=b[ri]; 
    66             b[ri]=t;
    67             
    68             t=c[le]; 
    69             c[le]=a[ri]; 
    70             c[ri]=t;
    71             le++; ri--;
    72         }
    73     }
    74     if(l<ri) 
    75     sort(l,ri);
    76     if(le<r) 
    77     sort(le,r);
    78 }
  • 相关阅读:
    spring(二) AOP之AspectJ框架的使用
    spring(一) IOC讲解
    struts2(六) 文件上传和下载
    导入Excel后绑定GridView实例
    类型“GridView”的控件必须放在具有 runat=server 的窗体标记内?
    只能在执行 Render() 的过程中调用 RegisterForEventValidation
    C# 连接SQL Server数据库的几种方式--server+data source等方式
    C#未将对象引用设置到对象的实例
    代码保存好
    在选定的数据源上未找到名为“TitleSub”的字段或属
  • 原文地址:https://www.cnblogs.com/charlesss/p/10146512.html
Copyright © 2011-2022 走看看