日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[启发式搜索/A*] [SCOI2005]骑士精神题解

發布時間:2025/4/16 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [启发式搜索/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]骑士精神题解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。