• 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 }
  • 相关阅读:
    服务器上传大小限制 --- 来自 FastAdmin 项目开发的引发的问题 (TODO)
    英语中的各种“破坏”
    PADS Layout CAM 的中高级焊盘选项
    FastAdmin 推荐 Git 在线学习教程
    Vue 将样式绑定到一个对象让模板更清晰
    jQuery动态的给页面中添加一条样式表的链接
    页面根据不同的情况添加不同的样式表
    jQuery屏蔽浏览器的滚动事件,定义自己的滚轮事件
    如何判断自己的浏览器支持的是javascript的那个版本
    ie下 iframe在页面中显示白色背景 如何去掉的问题
  • 原文地址:https://www.cnblogs.com/charlesss/p/10146512.html
Copyright © 2020-2023  润新知