SCOI2005 騎士精神

2022-07-16 19:36:13 字數 1066 閱讀 7588

qwq,ida*演算法太好玩了!

在這裡放一波我對迭代加深搜尋、a*演算法的理解(不一定對):

迭代加深搜尋就是列舉dfs的最大深度,然後跑dfs,去驗證不超過此深度的前提下是否有解;多用於答案上界很小或是搜尋範圍沒有上界,其實就是防止了dfs一搜到底。

a*演算法看起來像是乙個剪枝,定義估價函式,樂觀地估計從當前狀態出發的最終解,若比當前已找到的解還要差,不用多說,剪掉!

迭代加深搜尋又叫ids,用在一起就叫ida*了。。。

說說這道題,從看完課件裡的分析到a掉沒用多少時間,可能ida*的做法比較固定。不過最可能的原因,就像課件裡講的,這類題最關鍵的就是找到估價函式。

估價函式找的時候往往需要轉化一下,每次移動都會改變乙個非空格子的狀態,那麼最少移動步數一定大於等於不相同格仔的數目。一開始我只是單純地掃了一下統計不同的個數,但忽略了一點,一次移動會使兩個格仔發生變化:初始的空格子和移動後的空格子。這樣,並不是已移動的步數加上不相同格仔的數目大於當前解就剪枝,而是將兩數之和減1再比較。

1 #include2

const

int aim[6][6]=,

4 ,

5 ,

6 ,

7 ,

8 9};

10const

int mov[8][2]=,,,,,,,};

11int t,mt[6][6

],ans,maxd;

12void dfs(int d,int x,int

y) 18}19

if(flag)

23if(d+diff-1>maxd) return;24

for(int i=0;i<8;++i) 33}

34int

main()

45int flag=0

;46 ans=25;47

for(maxd=0;maxd<=15;++maxd) 50}

51if(!flag) printf("

-1\n");

52}53return0;

54 }

ac**

SCOI2005 騎士精神

乙個比較直接的思路是bfs爆搜,但這樣只能拿20分,所以考慮優化。在測試樣例時能夠看到深度為7的時候很快就跑出來了,在結合本題最大深度是15,所以可以用雙向bfs來優化,即從兩邊各跑7或8的深度,最後用map合併,有點類似折半搜尋。另外有一些需要注意的小細節已經在 中注釋。code include ...

SCOI2005 騎士精神

輸入格式 第一行有乙個正整數t t 10 表示一共有n組資料。接下來有t個5 5的矩陣,0表示白色騎士,1表示黑色騎士,表示空位。兩組資料之間沒有空行。輸出格式 對於每組資料都輸出一行。如果能在15步以內 包括15步 到達目標狀態,則輸出步數,否則輸出 1。輸入樣例 1 複製2 10110 01 1...

SCOI2005 騎士精神 IDA

棋盤太大,狀態數太多,無法像八數碼那樣用雜湊 bfs去做,但是用dfs也會t掉,這個時候可以考慮ida 即 迭代加深搜尋 a 剪枝。這題的h n 就是當前與目標棋盤不同的棋子數量。在一顆含有答案的子樹中,我們至多需要再走h n 步,就可以找到答案 因此,當當前步數 h n 最大可走步數時,就可以剪枝...