T1游戏
Description
Alice和Bob在玩一个游戏,游戏是在一个N*N的矩阵上进行的,每个格子上都有
一个正整数。当轮到Alice/Bob时,他/她可以选择最后一列或最后一行,并将其删除,但
必须保证选择的这一行或这一列所有数的和为偶数。如果他/她不能删除最后一行或最后一
列,那么他/她就输了。两人都用最优策略来玩游戏,Alice先手,问Alice是否可以必胜?
一道dp题,
我们可以从右上角开始,逐一枚举{当最终点落在(i,j)上的输赢情况},
没有平局,所以只需要考虑是否为偶数和是否必胜,
于是就可以进行判断,
如果 当前列为偶数,且去除此列后的最右下角的点必输,那么这个点可以标记做必胜,
同理 当前行为偶数,同样判断取出后的情况即可。
用前缀和(sum)来优化。
当 sum[i][j]-sum[i][j-1])%2==0 dp[i][i]=max(dp[i][j-1]^1,dp[i][j]);
当 sum[i][j]-sum[i-1][j])%2==0 dp[i][i]=max(dp[i-1][j-1]^1,dp[i][j]);
于是
#include<bits/stdc++.h> using namespace std; bool dp[1005][1005]; int t,f[1005][1005],n; int main() { cin>>t; while(t--) { memset(f,0,sizeof(f)); memset(dp,0,sizeof(dp)); scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%d",&f[i][j]); f[i][j]=f[i][j]+f[i-1][j]+f[i][j-1]-f[i-1][j-1]; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(dp[i][j-1]==false) if((f[i][j]-f[i][j-1])%2==0) { dp[i][j]=1;continue; } if(dp[i-1][j]==false) if((f[i][j]-f[i-1][j])%2==0) { dp[i][j]=1;continue; } } if(dp[n][n]) printf("W "); else printf("L "); } }