http://www.lydsy.com/JudgeOnline/problem.php?id=3106

白棋如果第一步不能贏,那麼一定輸

因為可以黑棋走的距離比白棋大,黑棋可以下一步吃掉白棋,也可以下一步離開白棋的吃子範圍

n才20,我們可以dfs搜尋所有的局面求黑棋取勝的回合數

記錄當前狀態到遊戲結束的回合數

如果現在白棋走,那它要儘可能的拖延時間,所以就是所有的後繼狀態取大

如果現在黑棋走,那它要儘快的取勝,所以就是所有的後繼狀態取小

邊界是當兩個棋子到同一位置時,根據前面的分析,應該必須是黑棋完成的最後一步

而dfs到下一回合,雙方互換

所以當前如果是白棋,就return 0

如果是黑旗,就return 無窮大

#include<cstdio>
#include<algorithm> using namespace std; int n; int dp[][][][][][]; int dfs(int who,int now,int r1,int c1,int r2,int c2)
{
if(now>n*) return n*;
if(r1==r2 && c1==c2) return who ? n* : ;
if(dp[who][now][r1][c1][r2][c2]) return dp[who][now][r1][c1][r2][c2];
int ans;
if(!who)
{
ans=;
if(r1>) ans=max(ans,dfs(,now+,r1-,c1,r2,c2));
if(r1<n) ans=max(ans,dfs(,now+,r1+,c1,r2,c2));
if(c1>) ans=max(ans,dfs(,now+,r1,c1-,r2,c2));
if(c1<n) ans=max(ans,dfs(,now+,r1,c1+,r2,c2));
}
else
{
ans=n*;
if(r2>) ans=min(ans,dfs(,now+,r1,c1,r2-,c2));
if(r2>) ans=min(ans,dfs(,now+,r1,c1,r2-,c2));
if(r2<n) ans=min(ans,dfs(,now+,r1,c1,r2+,c2));
if(r2<n-) ans=min(ans,dfs(,now+,r1,c1,r2+,c2));
if(c2>) ans=min(ans,dfs(,now+,r1,c1,r2,c2-));
if(c2>) ans=min(ans,dfs(,now+,r1,c1,r2,c2-));
if(c2<n) ans=min(ans,dfs(,now+,r1,c1,r2,c2+));
if(c2<n-) ans=min(ans,dfs(,now+,r1,c1,r2,c2+));
}
ans++;
return dp[who][now][r1][c1][r2][c2]=ans;
} int main()
{
int r1,c1,r2,c2;
scanf("%d%d%d%d%d",&n,&r1,&c1,&r2,&c2);
if(abs(r1-r2)+abs(c1-c2)<=)
{
printf("WHITE 1");
return ;
}
printf("BLACK %d",dfs(,,r1,c1,r2,c2));
}