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

    发现我自己好像不太会做这种题目

    但是还是发现有一些套路的

    就是拿出中间相邻的两项来进行比较

    我们拿出(i,j)这相邻的两项,设(x)表示所有排在(i)还有(j)之前的人左手上的数的乘积,那么(i)在前的充分条件是

    [frac{x*a_i}{b_j}<frac{x*a_j}{b_i} ]

    前面那个柿子是(i)排在前面时(j)能获得的收益,后面则是(j)排在前面的收益

    我们继续化一下柿子

    [a_i*b_i<a_j*b_j ]

    所以我们以(a_i*b_i)为关键字从小到大排序就好了

    之后还有一些非常相似的题目

    比如说排队接水这种非常入门的题目了

    
    有n个人在一个水龙头前排队接水,假如每个人接水的时间为ai,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小。
    
    

    首先但凡有点常识的人应该都知道这个时候应该尽量让接水时间少的人在前,这也非常好感性理解,但是我们同样也可以使用上面的那个方法来说明这一点

    我们设(i,j)为相邻的两个人,那么(i,j)之前所有人的总接水时间为(s),如果(i)排在(j)前面,则需要满足

    [s+s+a_i<s+s+a_j ]

    (s+a_i)(i)排在前面(j)的等待时间,(s+a_j)(j)排在前面(i)的等待时间

    根据上面那个柿子我们可以推出(a_i<a_j),于是我们就应该以(a_i)为关键字从小到大排序

    这个问题还有一个强化版,就是给每一个排队接水的人加上了一个权(b_i),要求使得(sum_{i=1}^npre_i*b_i)最小,(pre_i)为第(i)个人的等待总时间

    我们还是按照刚才的套路来,设(i,j)为相邻两人,(i,j)之前所有人的总接水时间为(s),如果(i)排在(j)前面,则需要满足

    [s*b_i+(s+a_i)*b_j<s*b_j+(s+a_j)*b_i ]

    那么就有

    [s*b_i+s*b_j+a_i*b_j<s*b_j+s*b_i+a_j*b_i ]

    于是就有

    [a_i*b_j<a_j*b_i ]

    也就是

    [frac{a_i}{b_i}<frac{a_j}{b_j} ]

    所以我们以(frac{a_i}{b_i})为关键字从小到大排序就好了

    我好像还没有写国王游戏,需要高精度实在是恶心

  • 相关阅读:
    深入浅出Blazor webassembly之程序配置
    深入浅出Blazor webassembly之通过CascadingValue组件实现向子级组件传值
    深入浅出Blazor webassembly之数据绑定写法
    深入浅出Blazor webassembly之浏览器WSAM性能测试
    重构的秘诀:消除重复,清晰意图
    在多数据源中对部分数据表使用shardingsphere进行分库分表
    logstach http input
    Addax 备忘
    WIN10下面0x00000bcb共享打印机无法连接怎么办?
    Calcite(二): 从list到tree的转换1
  • 原文地址:https://www.cnblogs.com/asuldb/p/10207890.html
Copyright © 2011-2022 走看看