[启发式搜索/A*] [SCOI2005]骑士精神题解
生活随笔
收集整理的這篇文章主要介紹了
[启发式搜索/A*] [SCOI2005]骑士精神题解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
洛谷-騎士精神
啟發式搜索-A*
估價函數
對于當前狀態,我們可以將其與目標狀態對比,得到一個預估的代價,即最少(不一定滿足題意)的代價,得到這個代價的函數叫做估價函數
對于一個最短路問題來說,我們可以定義一個如下的函數式來表示搜索的過程
\[ f^*(x)=g^*(x)+h^*(x) \]
其中,f*(x)為從x到目標節點預估的總代價,g*(x)表示目前到達x點已經付出的代價,h*(x)表示預估從x到目標的最小代價,如上題(騎士精神)中,f(x)用迭代加深枚舉出來,g(x)為已經走的步數(已知),h*(x)則可表示為目前局面與目標局面的不同點的個數。
上題代碼
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; int a[5][5]; int _std[5][5]= {{1,1,1,1,1},{0,1,1,1,1},{0,0,-1,1,1},{0,0,0,0,1},{0,0,0,0,0} }; int dx[]={0,-2,-2,-1,-1,1,1,2,2}; //重點,剪枝,兩邊對稱并在下面判斷防止走回去 int dy[]={0,-1,1,-2,2,-2,2,-1,1}; int ans; int lim; int fc() {int ret=0;for(int i=0; i<5; i++) {for(int j=0; j<5; j++) {if(a[i][j]!=_std[i][j]) {ret++;}}}return ret; } void dfs(int x,int y,int step,int f) {int diff=fc();if(diff+step>lim)return;if(step>=ans)return;if(diff==0) {ans=step;return;}for(int i=1; i<=8; i++) {if(x+dx[i]<0||(x+dx[i]>4)) continue;if(y+dy[i]<0||(y+dy[i]>4)) continue;if(i+f!=9) {swap(a[x+dx[i]][y+dy[i]],a[x][y]);dfs(x+dx[i],y+dy[i],step+1,i);swap(a[x+dx[i]][y+dy[i]],a[x][y]);}} }int main() {int t;scanf("%d",&t);while(t--) {int x,y;ans=20;int dif=0;for(int i=0; i<5; i++) {for(int j=0; j<5; j++) {char tmp;cin>>tmp;if(tmp=='1') {a[i][j]=1;}if(tmp=='0') {a[i][j]=0;}if(tmp=='*') {a[i][j]=-1;x=i;y=j;}if(a[i][j]!=_std[i][j])dif++;}}for(int i=dif;i<=16;i++){lim=i;dfs(x,y,0,0);}printf("%d\n",ans==20? -1:ans);}return 0; }而對于上題的搜索則需要最優性剪枝,通過變化數組的遍歷方式防止走回去
轉載于:https://www.cnblogs.com/shulker/p/9832596.html
總結
以上是生活随笔為你收集整理的[启发式搜索/A*] [SCOI2005]骑士精神题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ2891 Strange Way
- 下一篇: day04--课后练习