把猴子和香蕉按照從左到右的順序編號,當每個猴子拿到對應順序的香蕉的時候所有猴子拿完香蕉花費的時間最少。比如說左起第乙個猴子應該拿左起的第一根香蕉,以此類推。
def assignbananastomonkeys(bananas,monkeys):
bananas.sort()
monkeys.sort()
res = 0
for i in range(len(bananas)):
res = max(res,abs(bananas[i]-monkeys[i]))
return res
每個猴子選擇其對應位置的香蕉,舉例,左起第乙個猴子應該拿左起的第一根香蕉
第i個猴子拿第i根香蕉
對於所有的分配方式,第i個猴子要麼拿到第i根香蕉或者沒有,我們暫時把第i個猴子拿第j根香蕉這種猴子香蕉對叫做亂序對,那麼,我們不失一般性的把所有亂序對拿出來,按照從左到右的順序把猴子和香蕉排序一次,得到monkeys和bananas兩個序列。
如果我們按照第i個猴子拿了第j根香蕉,第j個猴子拿了第k根香蕉的方式進行下去,最後必定會存在第m個猴子拿了第i根香蕉,也就是說,本質上來說,這些亂序對構成了多個長度不同的環。例子:第乙個猴子拿第二根香蕉,第二個猴子拿第一根香蕉,構成乙個長度為2的環。
因為這些亂序對構成了多個環,不失一般性,我們暫時就假設前i個猴子亂序和前i根香蕉亂序,構成長度為i的環,並且這個環不能再拆出新的子環。我們只需要證明對長度為i的環,其花費的最大時間大於按照順序拿即可。
對於所有的這些環,我們要遵循兩個前提。第乙個是,每個猴子必定不應該去拿距離大於它拿對應序號的香蕉的距離的香蕉,這樣的拿法是沒有意義的,必定達不到最優解。第二個點,亂序的根本原因是因為多步決策下第k個猴子拿了離他更近的香蕉,而這根香蕉不是第k根香蕉,否則滿足第乙個前提下一部分猴子貪婪,一部分不貪婪,那麼該環一定可以繼續拆分。這種情況下該環必定是第i個猴子取第一根香蕉,而這種情況下,此時其需要走的路徑是最左最右兩個端點連起的整條直線的長度,大於按照順序取。得證
那麼為什麼長度為i的環必定是最後乙個猴子拿第i根香蕉,考慮第乙個猴子為什麼不拿第一根香蕉,必定是因為存在另一根香蕉離他更近,那麼此時對於所有的其他猴子來說,都不願意跑更遠的路去拿第一根香蕉,多步決策貪婪之後必定是第i個猴子拿了第一根香蕉,我們假設不是第i個猴子而是第k個猴子拿的第一根香蕉,那麼此時第k個猴子沒有遵循貪婪的原則,那麼此時就構成了乙個長度小於i的環,可以拆分出去,和我們的假設矛盾,因此必定是最後乙個猴子拿的第一根香蕉。
針對3中存在的所有構成環的亂序對,最終,所有亂序對中的猴子最終導致它們整體拿完香蕉所需要的時間要大於它們按照順序拿香蕉的所需要的時間,極端情況比如猴子位置重複,香蕉位置重複等,會出現等於的情況。
因此按照順序拿香蕉所花費的時間必定小於或者等於所有其他不按照順序拿香蕉的方式所花的時間。演算法正確性得證。
兩次排序加一次陣列遍歷
要使得繩子拆分之後積最大,其因子必定是2或者3
def ropebreak(n):
if n==2:
return 1
if n==3:
return 2
if n==4:
return 4
num = n//3
remain = n%3
if remain==1:
return 3**(num-1)*(remain+3)
elif remain==0:
return 3**(num)
else:
return 3**(num)*2
將繩子盡可能拆分成長度為3的部分,並且不能使得剩餘長度為1的情況出現
如果從dp的角度去思考,對於數n,拆分成兩部分的話,其最大值必定是n/2*n/2或者n//2*(n//2+1),對於n/2長度的部分繼續做拆分,直到其長度不能拆分使得其積大於其本身為止,即2或者3,此時其最優子結構為:
長度為n的繩子,其拆分之後積的最大值為dp[n]
其中dp[0:4] = [0,1,2,3,4]
對於數字num>=4,我們總可以拆分成(num-2)*num>=num
所以所有大於等於4的因子都可以被拆分,而又因為3*3大於2*2*2,所以每三個為2的因子可以被替換成兩個3的因子,因子為1沒有意義,因此最後結果中,因子必定為2或者3,同時2的個數必定不超過2.
這裡唯一耗時間的運算就是冪運算,也就是3**(n//3),複雜度為o(n//3),如果我們用快速冪演算法的話,複雜度可以變成o(log(n//3)),也就是o(logn)
貪心 合理分配
明顯的貪心法!就相當於 裡第乙個安排活動日期的題。我的ac include includeusing namespace std includestruct district bool cmp district a,district b sort v.begin v.end cmp 按 結束時間從小...
合理分配時間
最近有很多事情不明確,導致腦子裡有些混亂,不能顧及到所有,進而合理化分配時間。學長為我們明確了學習目標 1 招新 三摺紙,展板等 2 演算法 藍橋杯比賽的時間越來越近了 3 新技術 前後端的總學習計畫已經發過了,自己合理安排時間學習 4 之前的考核專案 目前沒必要花大量的時間去修改,可以先學新技術,...
子陣列之和最大 貪婪演算法
求子陣列的最大和 題目 輸入乙個整形陣列,陣列裡有正數也有負數。說明子陣列之最大和一定大於0 陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o n 例如輸入的陣列為1,2,3,10,4,7,2,5,和最大的子陣列為3,10,4,7,2,因此...