P4576 [CQOI2013]棋盘游戏-搜索,对抗搜索,博弈论,dfs

一个n*n(n>=2)棋盘上有黑白棋子各一枚。游戏者A和B轮流移动棋子,A先走。

  • A的移动规则:只能移动白棋子。可以往上下左右四个方向之一移动一格。

  • B的移动规则:只能移动黑棋子。可以往上下左右四个方向之一移动一格或者两格。

和通常的“吃子”规则一样,当某游戏者把自己的棋子移动到对方棋子所在的格子时,他就赢了。

两个游戏者都很聪明,当可以获胜时会尽快获胜,只能输掉的时候会尽量拖延时间。你的任务是判断谁会赢,需要多少回合。

比如n=2,白棋子在(1,1),黑棋子在(2,2),那么虽然A有两种走法,第二个回合B总能取胜。

https://www.luogu.org/problemnew/show/P4576

 这题好像就是传说中的对抗搜索。

好像有点像博弈,但是这道题几乎不需要博弈。

白棋一步一格,黑棋最多一步两格,这还用比嘛,差距悬殊啊,这就意味着白棋永远吃不掉黑棋,除非!!一开始黑棋就在白棋1步之内。白棋先走直接就给吃掉了,步数为1。否则!!!只可能黑棋吃掉白棋,且一定能吃掉。

这道题的中心思想:让黑棋尽快吃掉白棋(求min),让白棋尽量苟住(求max)

然后暴搜!!

#include
#include
#include
#include
using namespace std;
const int N=21;
const int inf=214748364;
int f[2][60][N][N][N][N];
int n,x1,y1,x2,y2;
int dfs(bool id,int step,int x1,int y1,int x2,int y2)//id==0:WHITE,id==1:BLACK
{
    int ans;
    if(step>3*n){
        return inf;
    }
    if(f[id][step][x1][y1][x2][y2]){
        return f[id][step][x1][y1][x2][y2];
    }
    if(x1==x2&&y1==y2){
        if(id) return inf;
        else return 0;
    }
    if(!id){
        ans=0;
        if(x1>1) ans=max(ans,dfs(1,step+1,x1-1,y1,x2,y2));
        if(x11) ans=max(ans,dfs(1,step+1,x1,y1-1,x2,y2));
        if(y11) ans=min(ans,dfs(0,step+1,x1,y1,x2-1,y2));
        if(x22) ans=min(ans,dfs(0,step+1,x1,y1,x2-2,y2));
        if(x21) ans=min(ans,dfs(0,step+1,x1,y1,x2,y2-1));
        if(y22) ans=min(ans,dfs(0,step+1,x1,y1,x2,y2-2));
        if(y2

 

你可能感兴趣的:(noip历年省选,搜索-dfs,博弈论)