题目链接:

https://leetcode-cn.com/problems/cat-and-mouse/

题目大意:


在一张无向图中,老鼠开始处于1号点,猫开始处于2号点,0号点是洞(猫不能进入),猫鼠交替移动(老鼠先)。
若老鼠能进入洞中,即老鼠胜,输出1;若猫能抓住老鼠(猫鼠同在一共点),即猫胜,输出2;否则则为平局,输出0。

解题思路:

这题可以用状态转移,将初始状态转移到已知的胜负的状态中。

我们可以使用一个三维数组 dp[i][j][k]dp[i][j][k]dp[i][j][k] 表示当老鼠在 iii 位置,猫在 jjj 位置,游戏进行了 kkk 轮时的胜负关系。

那么,我们可以先把确定的胜负关系罗列一下:

1.当老鼠位于0号点位时,老鼠必胜,即 dp[0][j][k]=1dp[0][j][k]=1dp[0][j][k]=1
2.当猫鼠位于相同位置时,猫必胜,即 dp[x][x][k]=2dp[x][x][k]=2dp[x][x][k]=2
3.当游戏进行2*n轮之后,即可认定为是平局的情况,即 dp[i][j][2∗n]=0dp[i][j][2*n]=0dp[i][j][2∗n]=0
(猫鼠都进行了n轮游戏,若仍未能分出胜负,则代表至少存在1个点老鼠已经到达两次,则说明无论对于猫鼠,都已经不再存在必胜点了)

而对于状态转移,可以遵循几个关系:

1.若下一步存在能够必胜的状态,则可以直接转移过去,即可直接确定必胜关系,结束遍历
2.若下一步只存在必败状态,则可直接确定必败关系,结束遍历
3.若下一步存在仍不确定(或必和)的状态,可先移动至此,再继续寻找后续必胜状态

因为移动的先后关系,我们可以将奇数回合当为老鼠移动,而偶数回合即为猫移动
对此,只需再注意一个点,即猫不能去到0号点即可

上代码:

class Solution {public:int n,dp[55][55][105];vector< vector<int> > p;int catMouseGame(vector<vector<int>>& graph) {n=graph.size();p=graph;memset(dp,-1,sizeof(dp));return GetResult(1,2,0);}int GetResult(int x,int y,int turn){if(turn>=2*n)   //回合数大于2*n,返回和状态return 0;if(dp[x][y][turn]==-1){if(x==0) dp[x][y][turn]=1;  //老鼠入洞,老鼠胜else if(x==y) dp[x][y][turn]=2;   //猫抓到老鼠,猫胜else dp[x][y][turn]=GetNext(x,y,turn);  //若不能确定,则继续找}return dp[x][y][turn];}int GetNext(int x,int y,int turn){int move=turn%2==0?x:y;   //确定当前回合移动的对象(猫、鼠)int defaultResult=move==x?2:1;   int result=defaultResult;  //将初始胜负状态确定为必败for(int i:p[move]){if(move==y&&i==0)  //猫不能到达0号点continue;int nx=move==x?i:x;int ny=move==y?i:y;int next=GetResult(nx,ny,turn+1);  //找下一个点的胜负关系if(next!=defaultResult){result=next;if(next!=0)   //若这个点不是和的状态(即必胜必败已定),即可退出遍历break;}}return result;}
};

[leetcode 913] 猫和老鼠(博弈、dp)相关推荐

  1. LeetCode 1185. 一周中的第几天 / 913. 猫和老鼠(博弈,动态规划) / 1576. 替换所有的问号

    1185. 一周中的第几天 2022.1.3 每日一题 题目描述 给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天. 输入为三个整数:day.month 和 year,分别表示日.月.年. ...

  2. LeetCode 1690. 石子游戏 VII(博弈DP)

    文章目录 1. 题目 2. 解题 1. 题目 石子游戏中,爱丽丝和鲍勃轮流进行自己的回合,爱丽丝先开始 . 有 n 块石子排成一排.每个玩家的回合中,可以从行中 移除 最左边的石头或最右边的石头,并获 ...

  3. LeetCode 486. 预测赢家(博弈DP)

    文章目录 1. 题目 2. 解题 1. 题目 给定一个表示分数的非负整数数组. 玩家 1 从数组任意一端拿取一个分数,随后玩家 2 继续从剩余数组任意一端拿取分数,然后玩家 1 拿,-- . 每次一个 ...

  4. Leetcode之动态规划(DP)专题-1025. 除数博弈(Divisor Game)

    Leetcode之动态规划(DP)专题-1025. 除数博弈(Divisor Game) 爱丽丝和鲍勃一起玩游戏,他们轮流行动.爱丽丝先手开局. 最初,黑板上有一个数字 N .在每个玩家的回合,玩家需 ...

  5. 天池 在线编程 双向取数(博弈DP)

    文章目录 1. 题目 2. 解题 1. 题目 https://tianchi.aliyun.com/oj/245679029019779851/254275128279634585 有一个长度为n的数 ...

  6. LeetCode 1025. 除数博弈(动态规划)

    1. 题目 爱丽丝和鲍勃一起玩游戏,他们轮流行动.爱丽丝先手开局. 最初,黑板上有一个数字 N .在每个玩家的回合,玩家需要执行以下操作: 选出任一 x,满足 0 < x < N 且 N ...

  7. [LeetCode]动态规划求解博弈问题

    博弈论是有趣又有用的知识,可以用来预测在特定的规则下,人们会做出怎样的行为,又会导致怎样的结果.利用博弈论来指导人们的行事法则甚至商业操作,比如著名的囚徒困境就被很好的利用在了商业竞争上.同样,Lee ...

  8. *【CodeForces - 859C 】Pie Rules (博弈dp,时光倒流)

    题干: You may have heard of the pie rule before. It states that if two people wish to fairly share a s ...

  9. LeetCode 编辑距离 II(DP)

    1. 题目 给你两个单词 s 和 t,请你计算出将 s 转换成 t 所使用的最少操作数. 你可以对一个单词进行如下两种操作: 删除一个字符 替换一个字符 注意: 不允许插入操作 题目保证有解 示例: ...

最新文章

  1. InnoDB调优-索引优化策略
  2. 【文文殿下】数论一些经典结论
  3. html 下拉框字体,怎么把select下拉菜单里的文字设置成左右滚动效果
  4. delphi 回调函数例子 用函数过程作为参数
  5. When.js 1.8.0 发布,Promises/A 的实现
  6. this指针_C++:07this指针
  7. Java实现生产消费模型的5种方式
  8. react前端封装接口弹出错误_react+ts打包发布后报Minified React error ..这种错误
  9. php如何使用memcached,PHP如何使用Memcached_PHP
  10. 简略讲述我的Fiddler的安转和配置过程
  11. Android源码下载(包括最新8.0版本)
  12. Mybatis一对一、一对多、多对多查询。+MYSQL
  13. 数据分析系列:生存分析(生存曲线分析、Cox回归分析)——附生存分析python代码。
  14. HIT-SC-Lab1 Convex Hull的算法实现(JAVA)
  15. 7-3 求分数序列前N项和 (15分)
  16. 基于极狐GitLab OpenAPI 开发一个仿dbt的版本管理WebIDE
  17. nginx实现反向代理及负载均衡
  18. [我也GitHub]我很焦虑, 我很暴躁!
  19. 长江商学院营销学李洋教授分析大数据与精准营销
  20. python用matplotlib画五角星_绘图:Matplotlib

热门文章

  1. 为公寓运营商提供SaaS管理系统,寓小二获贝壳找房5000万元A轮融资...
  2. 2021全球程序员收入报告,字节跳动年薪274万元排第5!
  3. 快捷键大全(实用版)
  4. [Pandas] 数据合并 pd.merge
  5. ZStack--级联框架
  6. 华为社招机考考什么_牛客网-华为-2020届校园招聘上机考试-软件类机考-3
  7. 【游戏程序设计】二维游戏示例-回合制Demo
  8. XLNet 详解(看不懂你来骂我)
  9. 5 个改善代码可读性的方法
  10. 小武学fpgastep5