zoukankan      html  css  js  c++  java
  • [博弈论/DP/成就感] 游戏

    【问题描述】
         Alice和Bob在玩一个游戏,游戏是在一个N*N的矩阵上进行的,每个格子上都有一个正整数。当轮到Alice/Bob时,他/她可以选择最后一列或最后一行,并将其删除,但必须保证选择的这一行或这一列所有数的和为偶数。如果他/她不能删除最后一行或最后一列,那么他/她就输了。两人都用最优策略来玩游戏,Alice先手,问Alice是否可以必胜?
    【输入格式】
        第一行:T,表示数据组数
        对于每组数据的第一行:N
        接下来N行,每行N个数,描述这个矩阵
    【输出格式】
        如果Alice必胜输出W,否则输出L
    【输入样例】
        2
        2
        2 4
        6 8
        3
        5 4 2
        1 5 9
        7 3 8
    【输出样例】
        L
        W
    【数据规模】
        100%数据满足 1<=N<=1000,1<=T<=5 保证每一行或每一列的和不会超过2*10^9
        30%数据满足 1<=N<=5
        50%数据满足 1<=N<=100
        70%数据满足 1<=N<=500
    【我的思路】

        由于这题是模拟赛自己想出来的,又是第一次考这种类型的题目,就很有成就感,于是标签就多了“成就感” qwq,既然是自己想出来的,那就写简单一点了。

        每次删最后一排或最后一列,用 bool类型 f(x,y) 表示 (1,1) 到 (x,y) 这个矩阵先手 能(1) 否 (0) 必胜。

        如果f(x,y-1)=0,若最后一列可以删,就赢了,即f(x,y)=1;

        同理f(x-1,y)=0,若最后一排可以删,就赢了,即f(x,y)=1;

        若 前二者 都等于 1,那么 如果当前可以删,对手确定必胜;如果当前不能删,我方已经输了。

                                   所以 这种情况无论如何必输。

        怎么看最后一排(列)能不能删呢?

        用二维前缀和维护就好了。

    #include<bits/stdc++.h>
    using namespace std;
    long long a[1005][1005];
    bool f[1005][1005];
    int n,T;
    int main()
    {freopen("game.in","r",stdin);
     freopen("game.out","w",stdout);
     scanf("%d",&T);
    for(int iii=1;iii<=T;iii++)
    {
    
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++)
          {
              scanf("%lld",&a[i][j]);
              a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+a[i][j];
          }
        memset(f,0,sizeof(f));
        //printf("--------------------
    ");
        /*
        for(int i=1;i<=n;i++)
        {
         for(int j=1;j<=n;j++)
          printf("%lld ",a[i][j]);            debug
         cout<<endl;
        }
        */ 
        //printf("--------------------
    "); 
        for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++)
          {
              if(f[i-1][j]==0) if((a[i][j]-a[i-1][j])%2==0) {f[i][j]=1;continue;}
              if(f[i][j-1]==0) if((a[i][j]-a[i][j-1])%2==0) {f[i][j]=1;continue;}
          }
        if(f[n][n]) printf("W
    ");else printf("L
    ");  
    }
    return 0;    
    }
  • 相关阅读:
    [BZOJ1013][JSOI2008]球形空间产生器sphere 高斯消元
    [Luogu1848][USACO12OPEN]书架Bookshelf DP+set+决策单调性
    [BZOJ1025][SCOI2009]游戏 DP+置换群
    [BZOJ1024][SCOI2009]生日快乐 搜索
    [BZOJ2002][Hnoi2010]Bounce弹飞绵羊 LCT
    「BZOJ 4565」「HAOI 2016」字符合并「区间状压DP」
    「BZOJ 5161」最长上升子序列「状压DP」
    「SPOJ TTM 」To the moon「标记永久化」
    「学习笔记」字符串大礼包
    「CF724G」Xor-matic Number of the Graph「线性基」
  • 原文地址:https://www.cnblogs.com/Miniweasel/p/9844636.html
Copyright © 2011-2022 走看看