对卿学姐的一道题目的自己的理解

来源:互联网 发布:网络借贷监管暂行办法 编辑:程序博客网 时间:2024/06/07 19:03

题目很简答:

下面是我复制粘贴的连接的原文:

卿学姐blog:

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

引入一道例题:

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。



下面是我对上面那个不等式的理解:

①当(n-(T/2-T/6))<0的时候,说明在T范围内的数字里面,能被2整除,并且把所有6的倍数排除在外,说明T范围内的数字一定是满足n个2的要求。

②当(n-(T/2-y/6))>0时,说明在T范围内,是2的倍数且不包含6的倍数的数字的个数小于n,同理对3的数字的个数小于m,那么这些还没有找到的数字要从T/6个数字里面找,如果该不等式成立,那么说明T的范围是符合要求的。否则T的范围是偏小的。


下面对n = 4, m = 2进行说明:T = 9

首先是2的倍数,并且不是6的倍数的数:2, 4, 8还有一个数没有找到

然后是3的倍数,并且不是6的倍数的数字: 3, 9 这已经符合对3的倍数的要求了

那么在T范围内6的倍数还剩下:6,正好可以给2的要求的数字。


直接将数字带入也是满足要求的,那么就这样。

本题采用二分的思想,复杂度为logn ,这也是二分的优点。


最后的最后,强烈安利卿学姐的blog真的给人以强大的干劲呢!!居然三年一直保持blog的更新,现在已经达到了2000篇,我的下一个目标就是切1000道题目,希望明年能够达成目标。

原创粉丝点击