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仍然無法滿足時間限制,那麼可以考慮題目性質進...