骑士精神——IDA*
Posted rsqppp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了骑士精神——IDA*相关的知识,希望对你有一定的参考价值。
不说了,这玩意就是个人生题,昨天晚上各种鬼,还有变量突然变成0的坑爹事情都出现了。
十五步以上算-1解。。。
总体思路,IDA*:
1.写个估值函数,这里我写的是和目标图的理想差异
2.枚举步数,根据步数和估值来决定剪枝。
3.一点经验,估值剪枝不要严格卡在步数上,可以适当放高上限,确保答案在搜索树上,换言之就是剪枝写的鲁棒一点,确保答案完整性,再去考虑效率,当然,这一题的条件可以很显然,g步最多接近最终局面g+1步,所以很容易写出剪枝。
黏上丑陋不堪的代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 6 using namespace std; 7 8 const int ans[5][5] = 9 {{1,1,1,1,1}, 10 {0,1,1,1,1}, 11 {0,0,2,1,1}, 12 {0,0,0,0,1}, 13 {0,0,0,0,0}, 14 }; 15 int Map[5][5]; 16 int flag = 0; 17 int dx[9] = {-2,-1,1,2,2,1,-1,-2}; 18 int dy[9] = {-1,-2,-2,-1,1,2,2,1}; 19 int gx() 20 { 21 int gx = 0; 22 for(int i = 0;i < 5;i++) 23 for(int j = 0;j < 5;j++) 24 if(Map[i][j] != ans[i][j]) 25 gx++; 26 return gx; 27 } 28 29 void dfs(int x,int y,int s,int k) 30 { 31 if(flag ) return; 32 int g = gx(); 33 if(g == 0){flag = 1;return;} 34 if(g + s > k+1) return; //g步最多改变g+1个位置所以上限为k+1。 35 for(int i = 0;i < 8;i++) 36 { 37 int newx = x+dx[i]; 38 int newy = y+dy[i]; 39 if(newx<0||newx>4||newy<0||newy>4) continue; 40 swap(Map[newx][newy],Map[x][y]); 41 dfs(newx,newy,s+1,k); 42 swap(Map[newx][newy],Map[x][y]); 43 } 44 45 } 46 int main() 47 { 48 int T; 49 cin>>T; 50 while(T--) 51 { 52 memset(Map,0,sizeof(Map)); 53 string a; 54 int sx,sy; 55 flag = 0; 56 for(int i = 0;i < 5;i++) 57 { 58 cin>>a; 59 for(int j = 0;j < 5;j++) 60 { 61 if(a[j] == \'*\'){ 62 sx = i; 63 sy = j; 64 Map[i][j] = 2; 65 }else if(a[j] >=\'0\'&&a[j] <= \'9\'){ 66 Map[i][j] = a[j]-\'0\'; 67 } 68 } 69 } 70 for(int i = 1;i <= 15;i++){ 71 dfs(sx,sy,0,i); 72 if(flag){ 73 cout<<i<<endl; 74 break; 75 } 76 } 77 if(!flag) cout<<"-1"<<endl; 78 } 79 return 0; 80 }
就酱吧。
以上是关于骑士精神——IDA*的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ1085:[SCOI2005]骑士精神——题解+IDA*粗略讲解