其實兩個東西都是堆。區別只不過乙個是利用差值等巧妙設計等效權值,另乙個則單純進行判斷。
反悔自動機
(名字是我自己起的)
貪心是不能反悔的。因為它就是選擇當前的最優解。
但是如果當前最優解不是全域性最優解怎麼辦?
我們可以設計一種反悔的方法,並且和貪心的手法結合。
使得貪心隨便選擇,都可以達到正解。
姑且叫反悔自動機。
基本的設計思路是:
每次選擇當前直觀上最接近最優解的方案。
但是發現不對。不是最優子結構
然後想辦法怎麼支援自動反悔。
0.邊有邊權,樹上選擇k個邊不相交的路徑,總和最大(權值有正有負)
求k次樹的直徑,每次把直徑上的邊權取反即可
1.經典問題:cf865d buy low sell high
每次用最小的**,等到乙個可以賺錢的天就賣出。
不對是因為:可能這個**的**要等到後面更貴的那一天再賣出。
利用做差,c-a=b-a+c-b,等效轉化
用最小的買最大的,然後把差值計入答案,把b放進去兩次,再取b為最小的時候,c-b的差值計入ans,相當於用a**以c賣出
相當於b沒有用,所以額外再加入一次b,以防後面需要用b**再d賣出。
2.類似的:
bzoj 2151
• 有乙個長度為n的環,選擇m個兩兩不相鄰的位置。
• 每個位置都有乙個價值vi,如果選擇這個位置就可以得到vi的價
值。• 求最大的價值總和,或輸出無解。
直觀來看,每次選擇能選擇的最大的價值。
為什麼不對?因為可能選擇了這個最大的,鄰居就不能選擇。例如1,5,6,5選擇了6,就只能再選擇1,不如5,5
而且,這個貪心的錯誤的點就是這裡。對於最優解位於其他的位置上的情況,這種貪心都是成立的。
考慮怎麼支援反悔。
還是利用差值。
用雙向鍊錶維護相鄰的關係。用堆維護所有權值的最大值。
選擇了a,把w[l[a]+w[r[a]-w[a]建成乙個新的點p,令這個p的l,r分別是:l[l[a]],r[r[a]],然後刪掉l[a],r[a],
每次取最大值即可。
因為,如果有a,b,c,d,(緊挨著就是相鄰),並且a+c>b+d,那麼,就有a+c-b>d
所以,即使我們先選擇了b,但是由於a+c-b>d,我們會接著選擇a+c-b,就相當於選擇a+c
反悔堆:
(名字也是我自己起的)(其實就是乙個堆)
這個不是無腦地隨便貪心了。因為沒有什麼等效權值的替換。
其實思路差不多。
我們還是按照乙個貪心策略貪心,然後找出來不足。
想辦法反悔。
和反悔自動機不同的是,這個要人工反悔。
例題:[jsoi2007]建築搶修——貪心反悔堆
有關AC自動機的fail樹
由於ac自動機fail的作用老是忘 在這裡記錄一下,以後複習也方便 首先,再字典樹上,每個點的fail,指向的就是和這個節點所表示的串擁有最長公共字尾的節點 這個的話,在建立完字典樹以後,直接bfs就可以弄出來了 然後ac自動機的經典例題,就是詢問x在y裡面出現了多少次 我們先在字典樹上面遍歷y 然...
暖 墟 AC自動機 AC自動機的總結與運用
kmp 匹配單串,線性掃瞄,在失配時用next陣列引導j指標回溯,進行下一步匹配。trie樹 多模式的匹配,構造26叉樹,同時記錄多個串的情況,記錄結尾,進行匹配。kmp trie樹 ac自動機 ac自動機 給乙個字典,再給乙個文字,問這個文字裡出現了字典裡的哪些字。可以用n個單詞的n次kmp演算法...
AC自動機的介紹與應用
一 概念 首先簡要介紹一下ac自動機 aho corasick automation,該演算法在1975年產生於貝爾實驗室,是著名的多模匹配演算法之一。乙個常見的例子就是給出n個單詞,再給出一段文章 長度是m 讓你找出有多少個單詞在文章裡出現過。要搞懂ac自動機,先得有字典樹trie的基礎知識 也有...