演算法筆記 雙端處理

2022-07-12 06:36:10 字數 2433 閱讀 1023

有的遞推演算法既可以從左向右推也可以從右向左推,這種特性賦予了我們乙個技巧,雙端處理法

當乙個東西對遞推陣列的影響僅限於左半部分或右邊部分,我們可以構造乙個反向遞推的陣列,把不受影響的部分合起來計算

ex最大欄位和

經典的最大子段和問題應該都很熟悉了,那麼如果把這個問題魔改一下,選取兩段不相交的子段,使得他們的和最大,該怎麼做?

先回憶一下最大欄位和的dp做法,記f[i]為以i為右端點的最大欄位和,那麼則可以從左向右遞推出每乙個f,問題解決

那麼如果我們要選取兩段,同時保證它們不相交,是不是可以選擇f最大的兩個點?

當然不行,這裡出現了乙個問題,你無法保證你選取的兩個區間是不相交的,因為f陣列只規定了右端點,而左端點是不確定的

我們希望找到乙個方法,確保兩個區間不相交

乙個簡單的做法就是再跑一邊dp,記g[i]為以i為左端點的最大欄位和

那麼任選兩點i,j(i

這樣我們列舉i,對於每個i,找到max g[j] (j>i),這樣就可以在o(n)的時間內找到最大雙子段和了(i要從n列舉到1,這樣max g[j]就可以遞推了)

ex清理石子

n堆石子排成一列,第i堆有a[i]顆石子,你每次可以在相鄰的兩堆中各取一顆石子,最終要把所有石子全部清除

當然,絕大多數情況下無法清除所有石子,幸好你有一項能力,在開始清理前,你可以交換任意兩堆相鄰的石子

請問你是否可以清理全部石子?(n<=1e5)

如果不考慮交換石子,那麼這會是一道簡單的題

先考慮最左端的石子,你想要清理它,就必須和第二堆一起清理,所以必須a[1]<=a[2],否則無法全部清理

清理完第一堆以後,第二堆變成了實際上的"第一堆",再用類似的方法清理它,以此類推

記f[i]為清理完[1,i-1]後,第i堆剩下的石子數,那麼有解的充要條件就是所有f[i]>=0

下面考慮交換操作對f陣列的影響

不難發現,交換操作只會影響f陣列後面的一部分,如果你交換i和i+1,那麼[1,i-1]不會受到影響

可以採用類似於ex最大欄位和的方法,反著再來乙個g陣列,g[i]表示清理完[i+1,n]後第i堆剩下的石子數量(既然可以從左遞推,那麼也可以從有遞推,因為清理第n堆石子也只有一種方法,和第n-1堆一起清理)

交換後i與i+1後先從左向右清理[1,i-1]再從右向左清理[i+2,n],如果清理過後第i堆和第i+1堆石子數量相等,那麼答案就是yes,否則可能需要交換另一對石子堆才行

有的遞推演算法既可以從左向右推也可以從右向左推,這種特性賦予了我們乙個技巧,雙端處理法

當乙個東西對遞推陣列的影響僅限於左半部分或右邊部分,我們可以構造乙個反向遞推的陣列,把不受影響的部分合起來計算

ex最大欄位和

經典的最大子段和問題應該都很熟悉了,那麼如果把這個問題魔改一下,選取兩段不相交的子段,使得他們的和最大,該怎麼做?

先回憶一下最大欄位和的dp做法,記f[i]為以i為右端點的最大欄位和,那麼則可以從左向右遞推出每乙個f,問題解決

那麼如果我們要選取兩段,同時保證它們不相交,是不是可以選擇f最大的兩個點?

當然不行,這裡出現了乙個問題,你無法保證你選取的兩個區間是不相交的,因為f陣列只規定了右端點,而左端點是不確定的

我們希望找到乙個方法,確保兩個區間不相交

乙個簡單的做法就是再跑一邊dp,記g[i]為以i為左端點的最大欄位和

那麼任選兩點i,j(i

這樣我們列舉i,對於每個i,找到max g[j] (j>i),這樣就可以在o(n)的時間內找到最大雙子段和了(i要從n列舉到1,這樣max g[j]就可以遞推了)

ex清理石子

n堆石子排成一列,第i堆有a[i]顆石子,你每次可以在相鄰的兩堆中各取一顆石子,最終要把所有石子全部清除

當然,絕大多數情況下無法清除所有石子,幸好你有一項能力,在開始清理前,你可以交換任意兩堆相鄰的石子

請問你是否可以清理全部石子?(n<=1e5)

如果不考慮交換石子,那麼這會是一道簡單的題

先考慮最左端的石子,你想要清理它,就必須和第二堆一起清理,所以必須a[1]<=a[2],否則無法全部清理

清理完第一堆以後,第二堆變成了實際上的"第一堆",再用類似的方法清理它,以此類推

記f[i]為清理完[1,i-1]後,第i堆剩下的石子數,那麼有解的充要條件就是所有f[i]>=0

下面考慮交換操作對f陣列的影響

不難發現,交換操作只會影響f陣列後面的一部分,如果你交換i和i+1,那麼[1,i-1]不會受到影響

可以採用類似於ex最大欄位和的方法,反著再來乙個g陣列,g[i]表示清理完[i+1,n]後第i堆剩下的石子數量(既然可以從左遞推,那麼也可以從有遞推,因為清理第n堆石子也只有一種方法,和第n-1堆一起清理)

交換後i與i+1後先從左向右清理[1,i-1]再從右向左清理[i+2,n],如果清理過後第i堆和第i+1堆石子數量相等,那麼答案就是yes,否則可能需要交換另一對石子堆才行

演算法導論 10 1 5 雙端佇列

棧的插入和刪除操作都是在一端進行的,而佇列的插入和刪除卻是在兩頭進行的。另有一種雙端佇列 deque 其兩端都可以做插入和刪除操作。對於乙個用陣列構造的雙端佇列,請寫出四個在兩端進行插入和刪除的操作的過程,要求執行時間都為o 1 next p,l 1 if p l 2 then ret 1 3 el...

演算法題 雙核處理

時間限制 1秒 空間限制 32768k 一種雙核cpu的兩個核能夠同時的處理任務,現在有n個已知資料量的任務需要交給cpu處理,假設已知cpu的每個核1秒可以處理1kb,每個核同時只能處理一項任務。n個任務可以按照任意順序放入cpu進行處理,現在需要設計乙個方案讓cpu處理完這批任務所需的時間最少,...

BWT表的雙端匹配演算法

先對reference取反 gcaga 再對取反後的 reference顛倒位置 agacg reference 右移 cgtctagacg gcgtctagac cgcgtctaga acgcgtctag gacgcgtcta agacgcgtct tagacgcgtc ctagacgcgt tc...