当前位置:网站首页>2022牛客多校六 M-Z-Game on grid(动态规划)
2022牛客多校六 M-Z-Game on grid(动态规划)
2022-08-08 23:06:00 【AC__dream】
题目:
样例输入:
2
3 3
..B
..B
BB.
1 3
...样例输出:
no no yes
no yes no题意:两个人在 𝑁∗𝑀 N∗M 的网格上轮流移动一个棋子。棋子初始位为 (1,1) (1,1) ,每次只能向某一维的正方向移动一格。网格上有一些特殊点,移到标 ’A’ 的点先手胜,移到标 ‘B’ 的点先手败,没有移到特殊点且不能再移动棋子则为平局。问先手是否有必胜、必平局、必败的策略。
分析:这是一道动态规划的题目,设f[i][j][0/1/2]=true/false表示从(i,j)走到(n,m)Alice(有/无)(必胜/平局/必败)方案,由于三种方案转移方法是相同的,我接下来就拿必胜状态来进行动态方程的推导。我们从位置(i,j)只能走到(i+1,j)和(i,j+1)两个格子其中的一个。看到这个状态表示也能大概想到我们的动态转移方程是逆着进行的,也就是从后往前递推,所以当我们更新到位置(i,j)时,位置(i+1,j)和位置(i,j+1)的状态就已经被更新好了,那么假如走到位置(i,j)时轮到Alice操作了,也就是(i+j)是偶数的情况,由于Alice的操作是我们可控的,所以只要位置(i+1,j)和位置(i,j+1)有一个位置是必胜态,那么Alice就能获胜,所以也就是说f[i][j][0]=f[i+1][j][0]|f[i][j+1][0],当然要保证位置(i+1,j)和位置(i,j+1)是合法的,也就是说i+1<=n,j+1<=m,那么假如走到位置(i,j)时轮到Bob操作了,由于Bob的操作是不可控的,所以我们只有同时保证位置(i+1,j)和位置(i,j+1)都是必胜态我们才能保证我们想要的结果发生,也就是说f[i][j][0]=f[i+1][j][0]&f[i][j+1][0],同样的也需要保证位置是合法的。我们按照上面的分析思路同样可以分析平局和必败的情况,这里就不赘述了,细节见代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=5e2+10;
char s[N][N];
bool f[N][N][3];//f[i][j][0/1/2]=true/false表示从(i,j)走到(n,m)Alice有/无必胜/平局/必败方案
int main()
{
int T;
cin>>T;
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
for(int j=1;j<=m;j++)
for(int k=0;k<3;k++)
f[i][j][k]=false;
}
for(int i=n;i>=1;i--)
for(int j=m;j>=1;j--)
{
if(s[i][j]=='A') f[i][j][0]=true;
else if(s[i][j]=='B') f[i][j][2]=true;
else//s[i][j]=='.'
{
if(i==n&&j==m)
{
f[i][j][1]=true;//特判不能走的情况
continue;
}
if((i+j)&1)//轮到Bob走
{
for(int k=0;k<3;k++)
f[i][j][k]=true;
if(i+1<=n)
for(int k=0;k<3;k++)
f[i][j][k]&=f[i+1][j][k];
if(j+1<=m)
for(int k=0;k<3;k++)
f[i][j][k]&=f[i][j+1][k];
}
else//轮到Alice走
{
if(i+1<=n)
for(int k=0;k<3;k++)
f[i][j][k]|=f[i+1][j][k];
if(j+1<=m)
for(int k=0;k<3;k++)
f[i][j][k]|=f[i][j+1][k];
}
}
}
if(f[1][1][0]) printf("yes ");
else printf("no ");
if(f[1][1][1]) printf("yes ");
else printf("no ");
if(f[1][1][2]) puts("yes");
else puts("no");
}
return 0;
}
边栏推荐
猜你喜欢

想要精准营销,从学习搭建一套对的标签体系开始丨DTVision分析洞察篇

Application Layer Protocol - RADIUS

新安装Laravel Framework 6.18.35 php artisan migrate 报错

Analysis of WLAN - Wireless Local Area Network

word文档标题怎么自动编号?

Qt入门(四)——连续播放图片(两种定时器的运用)

影响你各应用间网速的QoS你了解吗?

Mysql8.0.21 Community Server远程连接报错

MES docks with Simba to realize IMEI number writing and coupling test of Spreadtrum platform

meta learning
随机推荐
一个PHP算法,php数组一个二维数组拆分成多个子数组
Hi3516 使用 wifi模块
Go语言并发编程基础上下文概念是什么
JSDay2-两个数组的交集
【Bug解决】ValueError: Object arrays cannot be loaded when allow_pickle=False
Application Layer Protocol - RADIUS
选择排序
微信小程序开发一些函数使用方法
JSDay2- 长度最小的子数组
word文档标题怎么自动编号?
【Pytorch】学习笔记(一)
Kubernetes与OpenStack
【Verilog基础】关于芯片中信号串扰的理解
MySQL8.0 及 SQL 注入
支付宝 To 理财排行名称修改
免费ARP
如何搭建一套自己公司的知识共享平台
ArcPy要素批量转dwg
如何使用 Eolink 实现 API 文档自动生成
CTFSHOW_WEB入门web213