優雅的暴力
主要想總結一下搜索神奇的優化辦法。
第一梯隊:\(meet\) \(in\) \(the\) \(middle\) 雙搜
對於一些問題,從終點到起點和從起點到終點都是可逆的話,考慮meet in the middle。
可以將\(2^n\)搜索化為\(2^{\frac{n}{2}}\) 就可以接受了。
對於一些求方案數的問題,可以從起點搜到中間,再用數據結構存起來,再從終點搜到起點,統計答案。
第一梯隊:最優性剪枝
對於最優解的求法。若已經求出了一個可行的答案,假設當前答案已經大於這個已知答案了,則退出當前遞歸。
這種辦法最常用也最好用。
第一梯隊:可行性剪枝
經典例題就是蟲蝕算了。
根據學長的\(paper\),
搜索的復雜度\(=\)搜索的處理系數\(\times\)搜索的節點數。
根據當前得到的狀態,花費一定的代價檢查未來的情況是否非法,可以剪枝。
第一梯隊:啟發式搜索
少的節點先搜索,多的節點后搜索。先根據估價函數先搜索期望答案更好的。這是在最優性搜索里出現的。
第一梯隊:記憶化搜索
我覺得很多人弄反了,\(dp\)的實質是搜索,記憶化搜索。
配合哈希使用
第二梯隊:隨機化搜索
我不是搞笑的。這是真的。隨機化真的可以優化期望時間復雜度。就拿蟲食算舉例,將枚舉解的隊列\(random\)_\(shuffle\)一下,期望時間復雜度就真的降下來!!
第二梯隊:迭代加深
經典例題是數碼問題,對於數碼問題,我們可以從小到大先枚舉\(ans\),然后根據\(ans\)的大小確定搜索的深度。
第二梯隊:劣者靠后
經典例題是智慧珠游戲。
這道搜索如果從體積大的(優者)開始枚舉,可以飛快跑過。
實質上是將限制條件多的先搜索,這樣搜出來的狀態數會減少。
沒有優化復雜度,但是實際效果非常好。
第二梯隊:結合的搜索
將高效算法和搜索結合起來。
對於一些問題,問題的原型無法匹配上那一種高效算法,但是這個問題卻像那種高效算法的變種。這時可以先搜索,直到問題滿足了那一種高效算法的條件,再用高效算法。比如跑了搜索跑\(dp\),一邊二分一邊搜索。先搜索再網絡流。
第二梯隊:鴿王搜索
對於有些搜索,求的是最好的答案,但是有時候我們時限可能要到了,可是搜索還沒有完成。這個時候直接將已經搜出來的答案輸出出來,因為這個答案很可能是最優的,只是需要確認罷了。
什么時候腦洞打開就加。