P2324 SCOI2005 騎士精神

2022-04-29 22:03:10 字數 1923 閱讀 1956

ida*演算法

12個白騎士和12個黑騎士在乙個5*5的棋盤上走來走去,求最後走成目標局面的最小步數。

看不懂請走傳送門

ida

就是帶有迭代加深和估價函式優化的搜尋

估價函式:對未來搜尋深度的最優估計(通常是達不到的)

對於估價函式g,要求g≥現實步數(越接近越好,因為越接近能剪的枝就越多)。

當前步數+估價函式》迭代加深的maxdep,就剪枝以達到優化。

重點來了,認真聽講。

我們想象一下最優的情況:每次某騎士移動到空格後就到了自己的指定位置。此時需要的步數=不在原位的騎士的個數。而如果這個步數+已走步數都達不到≤限制步數,那就當場槍斃

然後估價函式就出現了:

int f[10][10]=,,,

,,

,};int check()

它的最大用處就是剪枝

除此之外可以想一想如果它返回0,就表示已達成目標狀態,所以檢驗dfs答案是也可用到它。

so:這是個好東西

高高興興的打出ida*:

#include#include#include#include#includeusing namespace std;

int t,a[10][10];

bool flag;//,chong[10][10];

int dx[10]=;

int dy[10]=;

int f[10][10]=,,,

,,

,};int check()

}return sum;

}void dfs(int xx,int yy,int step,int maxstep)

for(int i=1;i<=8;i++)

return;

}int main()

else a[i][j]=ch-'0';}}

if(!check())

for(int i=1;i<=15;i++)

}if(!flag) printf("-1\n");

}return 0;

}

然後你會驚奇地發現:「媽媽,我tle啦!」

所以單純的ida*不夠優,那麼就剪枝吧。

目前我想到的剪枝有兩個:

有了上面兩個優化中的乙個你就ac了,我只用了第乙個(絕對不是因為它好寫)

#include#include#include#include#includeusing namespace std;

int t,a[10][10];

bool flag;//,chong[10][10];

int dx[10]=;

int dy[10]=;

int f[10][10]=,,,

,,

,};int check()

}return sum;

}void dfs(int xx,int yy,int step,int maxstep)

for(int i=1;i<=8;i++)

return;

}int main()

else a[i][j]=ch-'0';}}

if(!check())

for(int i=1;i<=15;i++)

}if(!flag) printf("-1\n");

}return 0;

}

ida*+剪枝

P2324 SCOI2005 騎士精神

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

P2324 SCOI2005 騎士精神 題解

csdn同步 原題鏈結 簡要題意 給定乙個初始棋盤,每次乙個馬可以跳到空位 不考慮蹩腿問題 求到達目標棋盤的最小步數。本題其實是 八數碼難題 的乙個強化版,可以去看看 p1379 八數碼難題 題解.首先本題肯定是搜尋。咦?texttt 的效率不是嚴格不優於 texttt 的麼?為什麼還要用它呢?嗯,...

洛谷 P2324 SCOI2005 騎士精神

ida 練習題 1 ida iddfs a 1.1 iddfs用於單層 無限 情況但是解層數很少,這時可以限制dfs層數,id為每次的層數限制 1.2 a 具有估價函式,用於bfs快速求解 ida 就是將估價函式用於層數限制的dfs中,如果具有層數的dfs仍然無法滿足時間限制,那麼可以考慮題目性質進...