对抗搜索
\(minmax\) 搜索:
定义:
也叫对抗搜索,搜索时同时取最大/最小。
形式:
两人相互博弈,都希望自己的答案更优秀,即:
\(A\) 希望自己答案更大,\(B\) 希望 \(A\) 的答案更小。
解决:
在搜索时,我们进行人物的判断:
若当前是 \(A\) ,我们的转移方程中就取 \(max\)
若当前是 \(B\) , 我们的转移方程中就取 \(min\).
可能这样还不够详细,选一道例题分析一下:
这道题就是典型的对抗搜索类型的题目。
分析:
平局的状态很好选择,就是走的步数过多了,我们考虑能搜索到的情况:
\(A\) 希望移动多,所以对每个方向搜索时,取能移动的最大步数,更加优秀
\(B\) 希望移动少,所以取能移动的最小部署。
因为数据范围比较小,爆搜是可以的,最后判断是否重合即可。
#include<bits/stdc++.h>
using namespace std;
int dx[8]={0,1,0,-1,0,2,0,-2};
int dy[8]={1,0,-1,0,2,0,-2,0};
int f[2][81][21][21][21][21],inf=2e9,n;
int v,X1,Y1,X2,Y2;
int dfs(int opt,int y,int X1,int Y1,int X2,int Y2){
int res;
if(y>3*n) return inf;//步数过多
if(X1==X2&&Y1==Y2){
if(opt==0) return 0;
else return inf;
}
if(f[opt][y][X1][Y1][X2][Y2]) return f[opt][y][X1][Y1][X2][Y2];
if(!opt){
res=0;
for(int i=0;i<4;i++){
int xx=X1+dx[i];
int yy=Y1+dy[i];
if(xx>=1&&yy>=1&&xx<=n&&yy<=n)
res=max(res,dfs(opt^1,y+1,xx,yy,X2,Y2));
}
}
else{
res=inf;
for(int i=0;i<8;i++){
int xx=X2+dx[i];
int yy=Y2+dy[i];
if(xx>=1&&yy>=1&&xx<=n&&yy<=n)
res=min(res,dfs(opt^1,y+1,X1,Y1,xx,yy));
}
}
f[opt][y][X1][Y1][X2][Y2]=res+1;
return res+1;
}
int main()
{
cin>>n>>X1>>Y1>>X2>>Y2;
if(abs(X1-X2)+abs(Y1-Y2)<=1) printf("WHITE 1\n");
else{
v=dfs(0,0,X1,Y1,X2,Y2);
if(v>inf) printf("DRAW\n");
else printf("BLACK %d\n",v);
}
system("pause");
return 0;
}
例题:
不关注的有难了😠😠😠https://b23.tv/hoXKV9