问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

1728. 猫和老鼠 II : 博弈论 DP 困难题

发布网友 发布时间:2024-09-27 07:05

我来回答

1个回答

热心网友 时间:2024-10-02 09:00

题目描述

这是 LeetCode 上的 1728. 猫和老鼠 II ,难度为 困难。

Tag : 「博弈论」、「动态规划」、「记忆化搜索」

一只猫和一只老鼠在玩一个叫做猫和老鼠的游戏。

它们所处的环境设定是一个?rows x cols?的方格 grid?,其中每个格子可能是一堵墙、一块地板、一位玩家(猫或者老鼠)或者食物。

玩家由字符?'C'?(代表猫)和?'M'?(代表老鼠)表示。

地板由字符?'.'?表示,玩家可以通过这个格子。

墙用字符?'#'?表示,玩家不能通过这个格子。

食物用字符?'F'?表示,玩家可以通过这个格子。

字符?'C'?,?'M'?和?'F'?在?grid?中都只会出现一次。

猫和老鼠按照如下规则移动:

老鼠 先移动?,然后两名玩家轮流移动。

每一次操作时,猫和老鼠可以跳到上下左右四个方向之一的格子,他们不能跳过墙也不能跳出?grid?。

catJump 和?mouseJump?是猫和老鼠分别跳一次能到达的最远距离,它们也可以跳小于最大距离的长度。

它们可以停留在原地。

老鼠可以跳跃过猫的位置。

游戏有 $4$ 种方式会结束:

如果猫跟老鼠处在相同的位置,那么猫获胜。

如果猫先到达食物,那么猫获胜。

如果老鼠先到达食物,那么老鼠获胜。

如果老鼠不能在 $1000$ 次操作以内到达食物,那么猫获胜。

给你?rows x cols?的矩阵?grid?和两个整数?catJump?和?mouseJump,双方都采取最优策略,如果老鼠获胜,那么请你返回?true,否则返回 false。

示例 1:

输入:grid?=?["####F","#C...","M...."],?catJump?=?1,?mouseJump?=?2输出:true解释:猫无法抓到老鼠,也没法比老鼠先到达食物。

示例 2:

输入:grid?=?["M.C...F"],?catJump?=?1,?mouseJump?=?4输出:true

示例 3:

输入:grid?=?["M.C...F"],?catJump?=?1,?mouseJump?=?3输出:false

示例 4:

输入:grid?=?["C...#","...#F","....#","M...."],?catJump?=?2,?mouseJump?=?5输出:false

示例 5:

输入:grid?=?[".M...","..#..","#..#.","C#.#.","...#F"],?catJump?=?3,?mouseJump?=?1输出:true

提示:

$rows == grid.length$

$cols = grid[i].length$

$1 <= rows, cols <= 8$

$grid[i][j]$ 只包含字符?'C'?,'M'?,'F'?,'.'?和?'#'?。

grid?中只包含一个?'C'?,'M'?和?'F'?。

$1 <= catJump, mouseJump <= 8$

博弈论 DP

当时在 (题解) 913. 猫和老鼠 没能证出来更小 $K$ 值(回合数)的正确性,用的 $2n^2$ 做的 ,其余题解说 $2 n$ 合法,后来也被证实是错误的。

对于本题如果用相同的分析思路,状态数多达 $8 \times 8 \times 8 \times 8 \times 2 = 8192$ 种,题目很贴心调整了规则为 $1000$ 步以内为猫获胜,但证明 $K$ 的理论上界仍是困难(上次分析不出来,这次压根不想分析

如果忽略 $K$ 值分析,代码还是很好写的:定义函数 int dfs(int x, int y, int p, int q, int k) 并配合记忆化搜索,其中鼠位于 $(x, y)$,猫位于 $(p, q)$,当前轮数为 $k$(由 $k$ 的奇偶性可知是谁的回合)。

对边界情况进行讨论,移动过程中按照规则进行(四联通,移动最大距离为 mouseJump 和 catJump),注意一旦遇到边界或者墙就要截断。

Java 使用静态数组,用一个 int 代表双方所在位置,最大回合数 $K = 1000$,2022-05-10 可以过。这道题给的时间上限很高,我调整为 $K = 1500$ 跑成 $2.5s$ 也可以过。本来想要加个卡常,每 $200$ 轮检查一下运行总时长,尽量将时间压在 $850ms$ 以内,现在看来好像用不到。

代码:

import?java.time.Clock;class?Solution?{????static?int?S?=?8?*?8?*?8?*?8,?K?=?1000;????static?int[][]?f?=?new?int[S][K];?//?mouse?:?0?/?cat?:?1????String[]?g;????int?n,?m,?a,?b,?tx,?ty;????int[][]?dirs?=?new?int[][]{{1,0},?{-1,0},?{0,1},?{0,-1}};????//?mouse?:?(x,?y)?/?cat?:?(p,?q)????int?dfs(int?x,?int?y,?int?p,?int?q,?int?k)?{????????int?state?=?(x?<<?9)?|?(y?<<?6)?|?(p?<<?3)?|?q;????????if?(k?==?K?-?1)?return?f[state][k]?=?1;????????if?(x?==?p?&&?y?==?q)?return?f[state][k]?=?1;????????if?(x?==?tx?&&?y?==?ty)?return?f[state][k]?=?0;????????if?(p?==?tx?&&?q?==?ty)?return?f[state][k]?=?1;????????if?(f[state][k]?!=?-1)?return?f[state][k];????????if?(k?%?2?==?0)?{?//?mouse????????????for?(int[]?di?:?dirs)?{????????????????for?(int?i?=?0;?i?<=?b;?i++)?{????????????????????int?nx?=?x?+?di[0]?*?i,?ny?=?y?+?di[1]?*?i;????????????????????if?(nx?<?0?||?nx?>=?n?||?ny?<?0?||?ny?>=?m)?break;????????????????????if?(g[nx].charAt(ny)?==?'#')?break;????????????????????if?(dfs(nx,?ny,?p,?q,?k?+?1)?==?0)?return?f[state][k]?=?0;????????????????}????????????}????????????return?f[state][k]?=?1;????????}?else?{?//?cat????????????for?(int[]?di?:?dirs)?{????????????????for?(int?i?=?0;?i?<=?a;?i++)?{????????????????????int?np?=?p?+?di[0]?*?i,?nq?=?q?+?di[1]?*?i;????????????????????if?(np?<?0?||?np?>=?n?||?nq?<?0?||?nq?>=?m)?break;????????????????????if?(g[np].charAt(nq)?==?'#')?break;????????????????????if?(dfs(x,?y,?np,?nq,?k?+?1)?==?1)?return?f[state][k]?=?1;????????????????}????????????}????????????return?f[state][k]?=?0;????????}????}????public?boolean?canMouseWin(String[]?grid,?int?catJump,?int?mouseJump)?{????????g?=?grid;????????n?=?g.length;?m?=?g[0].length();?a?=?catJump;?b?=?mouseJump;????????for?(int?i?=?0;?i?<?S;?i++)?Arrays.fill(f[i],?-1);????????int?x?=?0,?y?=?0,?p?=?0,?q?=?0;????????for?(int?i?=?0;?i?<?n;?i++)?{????????????for?(int?j?=?0;?j?<?m;?j++)?{????????????????if?(g[i].charAt(j)?==?'M')?{????????????????????x?=?i;?y?=?j;????????????????}?else?if?(g[i].charAt(j)?==?'C')?{????????????????????p?=?i;?q?=?j;????????????????}?else?if?(g[i].charAt(j)?==?'F')?{????????????????????tx?=?i;?ty?=?j;????????????????}????????????}????????}????????return?dfs(x,?y,?p,?q,?0)?==?0;????}}

时间复杂度:令 $n$ 和 $m$ 分别为矩阵的长宽,最长移动距离为 $L$,复杂度为 $O(n^2 \times m^2 \times 1000 \times 4 \times L)$

空间复杂度:$O(n^2 \times m^2 \times 1000)$

最后

这是我们「刷穿 LeetCode」系列文章的第 No.1728 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

原文:https://juejin.cn/post/7096017698043199502

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
ef英语哪个好 EF英孚英语培训怎么样? 英孚英语好不好 EF英孚教育到底好不好 大佬们,麦芒7和荣耀10那个值得入手?2500以下的机子还有啥好推荐的么... 介绍几款2500元以前的手机 像素一定要高 其他的不做要求 近期想入手一部安卓手机,价格2200到2500左右…买HTC desire Z还是 三星... 笔记本忘记开机密码怎么办急死了 笔记本电脑屏幕开机锁忘记密码 怎么办?急死了 华硕笔记本电脑开机密码忘记了怎样找回?系统是Windows 7旗舰版... 3000元电脑最强组装太平洋电脑配件报价网(3000元电脑组装机配置单) 被减数,减数与差的和为200,差与减数的比为1:4,被减数,减数与差分别是多... 【LeetCode-刷题基础】数据结构复习——队列/栈 Python 实现的3种... ...家说,你可以像猪一样生活,但你不可能像猪一样快乐,他为什么... csol怎么查看自己有多少霸主组件 CSOL战魂如何获得和武器列表? 榻榻米风水上犯忌吗 这里,将会是更茂密的松树林用什么标点符号 榻榻米柜子对面对着墙好,还是打个矮邦好 中医推拿学校 I5 6300HQ和I7 6700HQ差距大吗 姓周女孩,名字中后两个字要一个带金、一个带木,名字名字总笔画是... 为什么橄榄球在中国的欢迎度不高? 取名字 姓张 取两个字的一个带金 一个带木的 比如(鑫银荣树)越多越好... 为什么中国体育项目里没有橄榄球? 如何在家长会上做好发言呢,有什么好的建议吗? 如何代表家长在家长会上发言! 没有箭头的张青排名第几? 这两种银元哪种比较值钱呢?大概市场价格多少啊现在? 什么银元最旺财 ...算式里,被减数,减数与差的和是200,减数是差的4被,减数是多少,差是多... 面试题 17.11. 单词距离 : 超简单双指针算法面试题 ...差与减数的比为1:4,被减数、减数和差分别是多少? 淋漓尽致意思 词语淋漓尽致意思 为什么我的mysql服务没了? 安装mysql后没有看到服务怎么办? 苹果11o官方微信,我的苹果4s序列号是DX3MTF2QFMLD,查询真伪及是否为翻... WeiXin11O、qq、COm怎样解封微信 微信祝福语代码怎么用? 微信ohh是什么意思,微信ohh意思介绍? UNRAID搭建中,i5 10400+华擎B460M-ITX如何搭配硬盘? 发动机排放故障灯亮了应该怎么办? 求人帮我看看我这配置玩使命召唤10 11 12可以玩吗?我同学说我这机子有... 空调在除湿状态下省电吗 (本文已过期)【月例】2020.10装机配置推荐(不含显卡,已更新亮机卡推荐... 发动机排放故障灯亮是怎么回事? 【装机帮扶站】第687期:又贵又便宜的十代i7+奔腾办公配置推荐(京东)_百... 网易云音乐怎么查看微信状态? 请问这种配置能玩《使命召唤9》吗?那10呢? 电脑PC端,重装系统后,微信如何恢复之前的所有聊天记录