生活随笔
收集整理的這篇文章主要介紹了
P2324 [SCOI2005]骑士精神(迭代加深搜索,dfs)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
文章目錄
解析
很顯然,讓馬走的話狀態記錄和轉移都會比較復雜
所以轉化成讓空位跳會更好做一點
但這不是重點
初看本題,其實第一感覺是bfs
但是狀態數理論上最差可以達到815,(當然基本不可能跑滿),是無法接受的
注意到,本題中出現了只需求15步以內的答案的要求,我們就想到使用迭代加深搜索,逐步擴大搜索樹的深度,這樣就能利用dfs的同時,保證最先出現的答案就是最優解。
但是,對于無解或答案接近15的情況來說,這個在時間復雜度上其實并沒有起到太多優化的作用
因此我們需要更好的剪枝策略
可以引入一個估價函數,記為h
其意義是最好情況下,當前狀況完成任務所需要的步數
再設當前步數為step,迭代的深度上限是maxstep,那么當——
step+h>maxstepstep+h>maxstepstep+h>maxstep
時,可以直接return
對于本題,估價函數可以是當前狀態與目標狀態(這里可以打個表)逐位比較,有不同則加一
(注意,因為當最后一步時,空位和馬會同時歸位,估計函數會減2,所以上面的式子應該對于本題有一個特殊的修改:
step+h>maxstep+1step+h>maxstep+1step+h>maxstep+1
通過這樣剪枝,就大大減少了不必要的搜索
使本題得以解決
(本題還有一個作用頗大的剪枝策略:就是記錄一下上一步跳的方向,防止搜索過程中出現來回橫跳的無意義搜索)
#include<bits/stdc++.h>
using namespace std
;
#define ll long long
const int N
=1e6+100;
const int mod
=20040313;
int read(){int res
=0,f
=1;char c
=getchar();while(c
<'0'||c
>'9'){if(c
=='-'){f
=-1;}c
=getchar();}while(c
>='0'&&c
<='9'){res
*=10;res
+=c
-'0';c
=getchar();}return f
*res
;
}
int mp
[8][8];
char s
[150];
int t
;
int dx
[9]={0,-1,-2,-2,-1,1,2,2,1},dy
[9]={0,-2,-1,1,2,2,1,-1,-2};
int jd
[7][7]={
{0,0,0,0,0,0},
{0,1,1,1,1,1},
{0,0,1,1,1,1},
{0,0,0,-1,1,1},
{0,0,0,0,0,1},
{0,0,0,0,0,0}};
int flag
=0;
int calc(){int cnt
=0;for(int i
=1;i
<=5;i
++){for(int j
=1;j
<=5;j
++){if(mp
[i
][j
]!=jd
[i
][j
]) cnt
++;}}return cnt
;
}
bool exist(int x
,int y
){return x
>=1&&x
<=5&&y
>=1&&y
<=5;
}
void dfs(int step
,int mx
,int x
,int y
,int pre
){int o
=calc();if(o
==0){printf("%d\n",step
);flag
=1;return;}if(o
+step
>mx
+1) return;for(int i
=1;i
<=8;i
++){if(i
==pre
) continue;int nx
=x
+dx
[i
],ny
=y
+dy
[i
];if(!exist(nx
,ny
)) continue;swap(mp
[x
][y
],mp
[nx
][ny
]);dfs(step
+1,mx
,nx
,ny
,i
<=4?i
+4:i
-4);swap(mp
[x
][y
],mp
[nx
][ny
]);if(flag
) return;}return;
}
int x
,y
;
int main(){t
=read();while(t
--){flag
=0;for(int i
=1;i
<=5;i
++){scanf("%s",s
+1);for(int j
=1;j
<=5;j
++){char c
=s
[j
];if(c
=='1') mp
[i
][j
]=1;else if(c
=='0') mp
[i
][j
]=0;else mp
[i
][j
]=-1,x
=i
,y
=j
;}}for(int k
=1;k
<=15;k
++){dfs(0,k
,x
,y
,0);if(flag
) break;}if(!flag
) printf("-1\n");}return 0;
}
總結
以上是生活随笔為你收集整理的P2324 [SCOI2005]骑士精神(迭代加深搜索,dfs)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。