淺談搜索入門

         搜索是OI beginners 的必修課,也是在各類比賽中十分通用的技巧。已近三年遼寧省的NOIP 成績爲例,我們假設一名選手掌握了基本的搜索和模擬算法,那麼TA的成績將如下所示(均達到遼寧省省一線):

2010 100 + 30 + 30 + 50 = 210

2009 100 + 50 + 30 + 40 = 220

2008 100 + 100 + 30 + 10 = 240

         下面就簡單談談各種常見的搜索並另附了一些可供練習的好題。

深度優先搜索

         深度優先搜索常用於求可行解、解的總數或者非深度最優的最優解。它可以輕鬆地用遞歸實現,當然可能也有人熱衷於非遞歸形式。遞歸框架如下:

  

 


廣度優先搜索

         廣度優先搜索常用於求深度最優的最優解。它一般用隊列來實現(如果爲了節省空間可以選擇取模的方式使用循環隊列,如最短路的SPFA算法)。其框架如下:

 


判重問題

         搜索過程中常常遇到搜索回同一種情況的時候,就像你可以乘坐154從育才北校去南校,也可以打車過去,總之到那之後你該幹嘛幹嘛!如果搜索到這樣一種情況,你即便再往下搜也只是重複了昨天的故事,全是無用功。這時,你就需要想辦法判斷你是是否回到了過去。我們通常開一個布爾數組來判重。

 

 


迭代加深搜索

         我很喜歡這個迭代加深,我認爲它平衡了深搜和廣搜的優缺點。它既像BFS那樣高效又像DFS那樣容易實現。迭代加深尤其適用於記錄結點信息比較麻煩的求最深度優解的題目。它得到的第一個可行解必然最優。其框架如下:


 

 

         可能有人有疑問:你不剛說完無用功的事兒麼!這麼來回重新搜索不是一堆無用功麼!在這裏我解釋一下:如果你把搜索過程想象成在一棵樹上的遍歷,那麼如果一棵樹比另一棵樹多一層那麼你要搜索的數據量就是翻了一番。

搜索的優化

         在做搜索題目時,我會反問自己這麼幾個問題,也是通常的優化思路。在做最後提到的那些題時可以體會到這些問題。

1.       以什麼作爲搜索對象?

2.       可否進行對解的預處理(動規、隨機化……)?

3.       採用什麼搜索順序?

4.       能否忽略明顯得不到合理解的結點?(可行性剪枝)

5.       能否忽略明顯得不到最優解的結點?(最優化剪枝)

抓住比賽的BUG

         比賽和考試不同於聯繫和學習,我們不得不承認功利至上,所以要掌握比賽的技巧。

         首先,我來談談打表。它常常用於函數類詢問,比如:n皇后解的總數、NOIP2008的火柴棒等式……實際操作就是在比賽時跑出所有輸入對應的解後,建立常量數組。

         其次是卡時技巧。方法是初始化計數器爲0,在每次訪問結點是計數器加1即可,當達到(時限 * 9 * 10 ^ 9)時,輸出當前最優解、當前解總數或者無解時的特判。

         最後說一下算法設計效率。我們期望的是得分效率高。記住,260分算法優於1100分算法!也就是說,滿分算法不一定是完滿算法!

推薦題目

名稱

考察點

來源

提交

生日蛋糕

強力剪枝

NOI 1999

POJ 1190

木棒問題

強力剪枝+搜索順序

ACM 中歐

POJ 1011

奶牛加密術

強力剪枝+搜索順序

USACO

USACO 4.1.4

質數方陣

強力剪枝

IOI 94

USACO 4.3.2

靶心數獨

搜索順序

NOIP 2009

RQNOJ 521

Betsy的旅行

強力剪枝

USACO

USACO 5.4.4

拼球問題

細心搜索

CEOI 1998

POJ 1725

BLOXORZ

細心搜索

POJ 07/08/05 月賽

POJ 3322

八數碼問題

康託判重

IOI 96

USACO 3.2.5

汽車問題

搜索順序

IOI 94

POJ 1167

騎士聚會

強力剪枝+預處理

IOI 98

USACO 3.3.3

13皇后

對稱判重

經典問題

USACO 1.5.4

N皇后可行解

啓發式修補

經典問題

POJ 3239

十五數碼問題

啓發函數

經典問題

POJ 1077

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章