標籤:演算法
本文出自:http://blog.csdn.net/svitter
原來的一篇可能是因為字數太長,一編輯就出問題,無奈,只好暫時寫一篇新的。
今天學習的內容是搜尋。
一.wide search 1.poj3307 cow
深度搜尋還要用棧。
廣度搜速度更快。
按照層次的順序訪問節點。
走n步可以到達的點,n-1不可以到達。絕對是最優解。
可以聯絡圖來想——周圍地區擴充。
re記住已經走過的點(如果轉換成樹呢?)
利用隊列來存點。
廣搜的空間大,深搜可以用一個棧來維護。(相對於廣搜空間少的多)
open表中。指向父節點的指標。(達到目標最少要走多少步。用層次編號來求。)
隊頭的節點是目標節點,搜尋完成。可以倒序輸出路徑。
注意:
1.判重複的標記。
2.層級編號
3.利用STL<queue>
poj3984迷宮
求最短到達迷宮口的路徑。
從隊頭取出狀態來擴充。擴充過(visit=0)則步擴充
基本是相同的題目。
可以利用遞迴來輸出路徑(即棧)。
改變隊列頭的位置,但是並不是刪除隊列中的元素。
以上基本為資料結構的內容。
BL 4980
迷宮變種。
類似於魔塔。
隊列為空白時結束,在資料結構中存一個時間變數。
把x擴充為可消除的點,第一次遇見擴充出改變。相當於擴充空間。
bl6044鳴人佐助。
花費量。花費最為有效查克拉。
什麼狀態。都是強調狀態。迷宮問題狀態是xy,對於不同的標記不同。
簡單的標記無法解決問題
類似動規
r, c, k所在行列,查克拉的數量。
可以對應的狀態變幻。
求鑰匙的鳴人
需要集齊k種鑰匙。必須集齊K種鑰匙才能救佐助。(1年級期末考試題目,程式設計實習)
POJ1729
jack,jill想距離最遠。
兩個人最近的直線距離最遠。
移動結束以後距離最遠,不考慮移動過城中的距離。
狀態:一對格子是一個狀態。
給一個限制條件,觀察是否可以走到。
假設一個限制條件。枚舉k看是否滿足。
枚舉所有的距離k。
求k的最大值。
深搜可能會慢一點,光搜應該會快。
利用二分法尋找來尋找一個更合適的值。(經典!線性搜尋)。
最近的最遠距離。
注意:
格子隊的判重問題。
個人的重複走問題。
利用標記判重。
POJ1077八數位
人工智慧的經典問題
也是強調狀態。
局面是一個狀態。
狀態壓縮方法。
狀態樹。(一個比較好的方式去記錄)
* 通性:狀態的判重。
狀態曾經出現過(不就是動規的子狀態麼)
一共9!
直到找到目標狀態。
能是o(1)最佳。
狀態的壓縮表示。**數位敏感性。
每一個狀態對應一個9位元。
int 可以表示一個狀態。
標誌位的序列。一個元素8bit一個需要。。。
減少標誌位的儲存空間。狀態數目只有9!
每個狀態空座0-8的一個排列。
每一個排列作為一個序號。
計算出排列序號x,數組小表就是a[x/8]的第x%8位。
*給定一個序號求排列。
狀態數字大小,時間的均衡。
作是否有解的判定。
*奇排列無法轉換成為偶排列。(離散數學)
移動0的位置,不會改變數列的奇偶性。可以證明。
POJ資料只有1組。hdu有多組資料。
bitset<STL>
2.compare dfs and bfs
3.雙向廣搜
DBFS是一種擴充。
利用兩個隊列。
* 一個擴充隊列已經擴充過,則可以停下了。
兩頭搜尋。
為何要快呢?
擴充出的總節點數目要少。
單向搜尋要m層才能找到答案,總的節點書目(1-n^m)/(1-n)
雙向廣搜,同樣是一共擴充m曾。兩邊各擴充出m/2層
則總結點數目2*(1-n^m-2)/(1-n)
* 選擇節點較少的那邊進行擴充。
4.A*演算法
啟發學習法搜尋演算法的一種
每個狀態n都會有一個估價函數。
優先考慮f值小額節點。
g(n)從其是狀態到狀態n的代價(不一定是最優的).
h(n)估計代價。
* 對估價函數進行特定限制,來確保知道最優解。
注意:
1.h(n)相容。
2.g(n)>=g*(n),g(n)>0
3.h(n)>=h*(n);
set:
multiset<>平衡二叉樹
hdu3000MS過的。比雙向廣搜慢。
人工智慧中的博弈*(可能狀態數目太多)
5.迭代加深搜尋演算法,也會重複搜尋
6.IDA*加深的A*演算法
poj2286
二.深搜剪枝 1.
北大ACM暑期培訓課程目錄(二)