每週演算法講堂,二分法

2022-03-31 15:52:42 字數 1462 閱讀 4820

又到了一周一度難得的週三了哦,你們找到女朋友了嗎?喵。

另外你們有沒有想我呢?

眾人:沒有。

嗚嗚嗚嗚嗚……

(擦乾眼淚。)

這週呢,我要講的演算法是二分法,至於為什麼要講這個演算法呢,我才不會告訴你們是因為這週的每週一題就是二分呢。

引入一道例題:

你需要找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,問你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個從小到大排好序的整數序列list,以及某待查詢整數x,我們的目標是找到x在list中的下標。即若有list i x,則返回i 否則返回 1表示沒有找到。二分法是先找到序列的中點list m 與x進行比較,若相等則返回中點下標 否則,若list m x,則...

演算法 二分法

二分法可以歸為兩大類 二分查詢演算法 二分排序演算法 二分合併演算法 演算法中經常用到二分查詢演算法,比如最常規的應用就是在乙個有序陣列中找特定的數,但是如何寫出乙個完整準確的二分法呢,邊界條件如何判斷,到底是等於還是不等?可能會困惱大家,比如說查詢第乙個等於5的數,那又在如何查詢呢?查詢最後乙個等...

二分法 演算法

二分法查詢,這個演算法要求資料要是有序的。比如有這樣的問題 找出乙個陣列中,兩個數的和小於等於15,然後輸出他們,否則就單獨輸出較大的數。binarysearch.cpp include using namespace std void binarysearch int array,int leng...