hdu2147 简单博弈dp

题意

  • 一个n*m的矩阵从右上角开始,两个人可以选择向左、下或左下移动,问先手能否取胜

思路

  • dp(i,j)表示到达i,j点的状态为必胜态还是必败态
  • 预处理2000*2000的dp,之后查询即可
  • 注意,空间给的很小,更新dp的时候最好用迭代的方式

实现

#include 
using namespace std;
bool dp[2002][2002];
typedef pair<int,int> pii;
#define fi first
#define se second
pii d[3];
inline void geng(int i,int j){
    for (int k=0;k<3;k++){
        int x = i + d[k].fi;
        int y = j + d[k].se;
        if (x<=0 || x>2000 || y <= 0 || y > 2000){
            continue;
        }
        dp[i][j] = dp[i][j] || !dp[x][y];
    }
}
int main(){
    d[0] = {1,0};
    d[1] = {0,-1};
    d[2] = {1,-1};
    dp[2000][1] = 0;
    for (int i=1;i<=2000;i++){
        for (int j=2000-i+1;j>0;j--){
            geng(j,i);
        }
        for (int j=i+1;j<=2000;j++){
            geng(2000 - i + 1,j);
        }
    }
    int n,m;
    while (scanf("%d%d",&n,&m) != EOF){
        if (n == 0)
            break;
        if (dp[2000 - n + 1][m]){
            puts("Wonderful!");
        }
        else{
            puts("What a pity!");
        }
    }
    return 0;
}

你可能感兴趣的:(ACM_Codeforces,ACM_DP,ACM_博弈论,ACM_HDU)