zoukankan      html  css  js  c++  java
  • 每周算法讲堂,二分法

    (原文是发送到UESTCACM微信的,所以欢迎大家关注哦~

    大家好,我是萌萌的微信酱!

    又到了一周一度难得的周三了哦,你们找到女朋友了吗?喵。

    另外你们有没有想我呢?

    众人:没有。

    呜呜呜呜呜……

    (擦干眼泪。)

    这周呢,我要讲的算法是二分法,至于为什么要讲这个算法呢,我才不会告诉你们是因为这周的每周一题就是二分呢。

    引入一道例题:

    Block Towers(来源codeforces 8VC Venture Cup 2016 - Elimination Round C题)
    题意:

    你需要找n个2的倍数,m个3的倍数,要求所有数都不一样

    你的目的是使得其中最大的数最小,然后问你这个数是多少呢?

    (0 ≤ n, m ≤ 1 000 000, n + m > 0)

    喵,题意讲完了~

    你们知道怎么做吗?

    只见迅雷不及掩耳盗铃之势,小郭同学一看到这道题,大呼:“这不是傻X题吗?我会做了!”

    小郭说:“这道题贪心就好了,由于是2和3之间的关系,肯定3得优先排前面,我先把3分配完,然后再弄2就好了!”

    小郭三下五除二就把代码写完,submit!

    duang,Wrong answer on pretest 4。

    哼,这周的主题就是二分,怎么能够让你贪心贪过去呢?(一脸傲娇

    第4个数据是 4 2,贪心的话,答案是10,但实际答案可以是9.

    这道题,如果正面去贪心的话,情况多多,比较麻烦,而且写着好累啊。

    那么我们怎么做呢?

    我们首先第一步,认识到这个答案是具有单调性的!

    如果T这个值是符合答案的,那么存在To>T,To显然也是符合答案的。

    因为To范围内的数显然比T多,而且To完全可以和T选取一模一样的数出来。

    反之,如果T是不符合答案的,如果To<T,显然To也是不符合答案的。

    然后我们就可以开始二分答案咯。

    我们把问题转换为,给你T,问你T范围内,是否能够分离出n个2的倍数,和m个3的倍数,并且这些数都是不一样的呢?

    只听喵的一声,沈宝宝说他会做了!

    沈宝宝说:“我们可以知道,T范围内,是2的倍数的数有T/2个,是3的倍数的有T/3个,即是2又是3的倍数的数,有T/6个,那么只要(max(0,n-(T/2-T/6))+max(m-(T/3-T/6),0))<=T/6就好了!" 。

    回答正确!奖励一颗糖!

    我们就二分答案,不断check就好了。

    我们首先找到答案的下界,l = 0,以及答案的上界r = 3*1000000。

    然后我们不断check((l+r)/2),如果(l+r)/2是符合答案的,那么根据单调性,显然[(l+r)/2,+∞)这个范围,都是符合答案的,那么我们令r = mid。如果(l+r)/2不符合答案,同理,根据单调性,(-∞,(l+r)/2]都是不符合答案的,我们就令l=mid。

    然后这样不断的进行check,直到l > r的时候,这样我们就能找到那个不符合和符合的分界线了~

    这条分界线,显然就是答案咯。

    喵,每一次check的时候,时间复杂度是O(1),我最多check logn次,所以二分的总时间复杂度是O(logn)的,完全可以接受。

    于是,我得到了Accepted。

    喵喵喵,二分就讲完了,你们懂了吗?

    如果不懂就给微信酱留言哦,或者在QQ群提问,微信酱会积极的解答的 ( ͡° ͜ʖ ͡°)

    米娜桑,加油吧~

  • 相关阅读:
    Java回调函数
    ajax数据展示过程中中文乱码问题
    ajax数据传递过程中中文乱码问题
    HDInsight - 1,简介
    HBase初探
    String类
    谈谈用户体验中的表单设计-实践篇
    谈谈用户体验中的表单设计-理论篇
    Win CE 6.0 获取手持机GPS定位2----示例代码 (C#)
    Win CE 6.0 获取手持机GPS定位1----基础知识 (C#)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5212649.html
Copyright © 2011-2022 走看看