首页 > 其他分享 >[ABC201D] Game in Momotetsu World 题解

[ABC201D] Game in Momotetsu World 题解

时间:2023-06-05 13:34:20浏览次数:45  
标签:return int 题解 ABC201D dfs 棋子 World dp Takahashi

Game in Momotetsu World

题目大意

在一个 \(n\times m\) 的网格中,存在红色和蓝色两种格子,红色格子用 - 表示,蓝色格子用 + 表示。

现在 Takahashi 和 Aoki 要在这个网格中进行游戏,游戏的规则如下:

  • 初始时,有一枚棋子摆放在左上角,即 \((1,1)\) 的位置。两名玩家的分数均为 \(0\)。
  • 双方轮流行动,Takahashi 先行动。
  • 在每次行动中,行动者可以选择将棋子向下或向右移动一格,但移动后不能超出网格。移动后如果棋子位于红色格子,那么行动者的分数 \(-1\),否则 \(+1\)。
  • 当棋子无法行动时,即位于 \((n,m)\) 时,游戏结束,得分高者为胜者。

现在告诉你网格的颜色情况,请你判断谁将会获胜。你可以认为这两名玩家都绝顶聪明。

思路分析

在打 AT 时,一个重要的原则是遇事不决就 DP。

考虑 DP,设 \(f_{i,j}\) 表示棋子位于 \((i,j)\) 时,Takahashi 的得分与 Aoki 的得分的差。

那么 Takahashi 的目标是最大化这个值,而 Aoki 则想要最小化这个值。

因为棋子只能向右或向下走,所以此时的回合数就是 \(i+j-1\)(回合从 \(1\) 开始)。那么容易写出状态转移方程:

\[f_{i,j}=\begin{cases}\max(f_{i+1,j}+a_{i+1,j},f_{i,j+1}+a_{i,j+1})&i+j-1\equiv 1\pmod2\\\min(f_{i+1,j}-a_{i+1,j},f_{i,j+1}-a_{i,j+1})&i+j-1\equiv 0\pmod2\end{cases} \]

(\(a_{i,j}\) 表示这一位的符号,即若 \((i,j)\) 为 +,那么 \(a_{i,j}\) 为 \(1\),否则为 \(-1\)。)

因为转移比较奇怪,所以考虑用记搜实现。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2020;
#define inf 0x3f3f3f3f

int a[N][N],dp[N][N];
int n,m;
char ch[N];

int dfs(int x,int y){
    if(x==n&&y==m) return 0;//到达边界
    if(dp[x][y]) return dp[x][y];
    if((x+y-1)%2==1){
        dp[x][y]=-inf;//记得赋初值和特判边界!
        if(x!=n) dp[x][y]=max(dp[x][y],dfs(x+1,y)+a[x+1][y]);
        if(y!=m) dp[x][y]=max(dp[x][y],dfs(x,y+1)+a[x][y+1]);
        return dp[x][y];
    }
    else{
        dp[x][y]=inf;
        if(x!=n) dp[x][y]=min(dp[x][y],dfs(x+1,y)-a[x+1][y]);
        if(y!=m) dp[x][y]=min(dp[x][y],dfs(x,y+1)-a[x][y+1]);
        return dp[x][y];
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s",ch+1);
        for(int j=1;j<=m;j++)
            a[i][j]=(ch[j]=='+')?1:-1;
    }
    int ans=dfs(1,1);//1 1 即为答案
    if(ans>0) cout<<"Takahashi\n";
    if(ans==0) cout<<"Draw\n";
    if(ans<0) cout<<"Aoki\n";
    return 0;
}

标签:return,int,题解,ABC201D,dfs,棋子,World,dp,Takahashi
From: https://www.cnblogs.com/TKXZ133/p/17457557.html

相关文章

  • P2048 超级钢琴 题解
    超级钢琴题目大意求出序列中长度在\([L,R]\)中的所有区间的区间和前\(k\)大的区间的区间和。思路分析暴力做法是把所有符合条件的区间扔进堆里,再弹出\(k\)个,时间复杂度\(O((n^2+k)\logn)\),可以拿到\(20\text{pts}\)的好成绩。但真的有必要全部加进去吗?不!我们设五......
  • P5445 路灯 题解
    路灯题目大意在\(n+1\)个站点之间有\(n\)盏路灯,给定\(0\)时刻所有路灯的亮灭情况,在接下来的\(q\)个时刻,每时刻会发生以下两种事件之一:切换某一盏路灯的亮灭。询问两点之间存在多少时刻使得两点之间的路灯全部亮起。思路分析一道不错的数据结构。首先分析题目......
  • Mysql 主从备份 Last_Errno: 1146 Last_Error: Error executing row event: 错误问题
    本人在做主从备份的时候发现了此问题! 1主数据库是已经把这个表删除了丛数据库也是没有备份这个表但是一直报这个错原因是bin-log日志有这个表 但是没记录到已经把这个表删除了 主从表同步实际从库是根据主库的bin-log二进制的SQL进行执行的 这是Mysql的一个BUG1......
  • 3. HelloWorld的实现
    恐惧是本能,行动是信仰(在此感谢尚硅谷宋红康老师的教程)1.新建Project-Class选择"NewProject":指名工程名、使用的JDK版本等信息。如下所示:接着创建Java类2.编写代码publicclassHelloWorld{publicstaticvoidmain(String[]args){......
  • erlang实现长连接管理问题解决
    具体参见:http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1/1.    erlang进程增加了休眠特性hibernate,支持连接从20w->70w;如上面的文章里面所说,使用hibernate后支撑的长连接飞涨。2.    40w时系统出现异常。查看系统日志发现socket......
  • CF1818D 题解
    一、题目描述:给你一颗$n$个点,$m$条边的简单无向图,可能不连通。我们定义$鱼图$为满足以下条件的无向图:$包含恰好\1\个环,环上有\1\个特殊的结点\u\,u\除了连在环上的\2\条边外还正好有\2\条边连向不在此环上的结点。$求是否存$鱼图$。若存......
  • 题解
    原题请见题目链接1.暴力求解这是我们线下水题赛的T1这里为初学者提供一个思路,假设我们现在刚入OI,在考场上如何怎么优雅的避免保灵显然我们只要用一个\(O(n)\)的暴力去扫描就行了,但是直接向后扫\(i+1,i+2\)这样走很容易寄。因为你在\(i+1\)跳的时候很容易把后面跳过了......
  • 【题解】[ABC304F] Shift Table(容斥)
    【题解】[ABC304F]ShiftTable题目链接ABC304F题意概述Takahashi和Aoki将在接下来的\(N\)天里兼职工作。Takahashi这\(n\)天的出勤情况由字符串\(S\)表示,其中\(S\)的第\(i\)个字符是#则表示他在第\(i\)天工作,第\(i\)个字符是.表示他在第\(i\)天休息......
  • 题解:【AGC054D】 (ox)
    题目链接Larry76牛牛首先考虑没有ox怎么做,就是将括号序列调成合法。\(|S|\)不大直接模拟一遍,记录\(now\)表示一个前缀权值,当遇到一个(时\(+1\),遇到一个)时\(-1\),当\(now<0\)的时候说明序列不合法即)多了,暴力向后找到第一个(交换到当前的)前面。这样我们......
  • Codeforces Round 876 (Div. 2)题解
    CodeforcesRound876(Div.2)A.TheGoodArray标签greedymath题意对于任意\(i\in\{1,2,\dots,n\}\),要求数列\(a\)满足前\(i\)个元素中至少有\(\lceil\frac{i}{k}\rceil\)个元素为\(1\),后\(i\)个元素中至少有\(\lceil\frac{i}{k}\rceil\)个元素为\(1\)。思......