尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

方格图路径计数 dp 的反射路径优化

方格图路径计数 dp 的反射路径优化
📅 发布时间:2026/6/18 23:17:15

很拗口的名字,其情景是这样的:

我们有一个点 \(B(n,m)\),需要求原点 \(A\) 到这个点的路径条数(限制只能向右、上走)。

平凡的题目做法很简单,我们一共走 \(n+m\) 步,其中 \(n\) 步向右,方案数 \(\binom {n + m} n\)。

但是进阶版的题目会给出一些限制,比如给出两条直线,要求不能碰到这两条直线。

如下图:\(n=6,m=3\),不能碰到 \(l_1:y=x+1,l_2:y=x-4\)。那么我们的路径有以下可能,箭头表示方向。

Part 1

我们正难则反,考虑容斥,扔掉那些碰到 \(l_1, l_2\) 的路径,从简单入手,先考虑碰到 \(l_1\) 的直线,如图中黑色线:

但这个碰到 \(l_1\) 太神秘了,而且原点和 \((n,m)\) 都在一侧,这让我们很难办,那我们如果有一个在 \(l_1\) 上方的点,此时,我们一条从原点到这个点的路线一定是经过 \(l_1\) 的。

我们考虑将碰到 \(l_1\) 的直线与这样的路径相对应,或者说用这种路径来生成所需路径。

我们发现,我们将原本路径从第一次碰到 \(l_1\)以后的部分都关于 \(l_1\) 做翻折(这个是否第一次不重要,只需要固定一个位置开始翻),形成图中紫色路径。那么,得到的路径终点为 \(B\) 关于 \(l_1\) 的对称点 \(B'\),我们发现这是一个一一映射,也就是只需要对原点到 \(B'\) 的路径计数即可,这同我们开始提到的平凡做法。

只碰到 \(l_2\) 直线同理,将 \(B\) 关于 \(l_2\) 对称得到 \(C\) 即可。

我们成功地分别算出了碰到 \(l_1\) 和 \(l_2\) 的方案数。

Part 2

我们定义一个序列,\(1212122211121 \cdots\) 表示路径碰到两条线的整个顺序。那么我们现在可以分别计算出序列中含有 \(1\)、含有 \(2\) 的个数了。同时,我们发现连续经过一条直线多次的情况已经被涵盖,那么下文讨论的序列都是将连续的 \(1\) 或 \(2\) 缩成一个之后的序列。

令 \(f(S)\) 碰线序列包含子串 \(S\) 的序列集合。答案应为:总情况数 - 碰到 \(l_1\) - 碰到 \(l_2\) + 既碰到 \(l_1\) 又碰到 \(l_2\)。即:

\[\begin{align*}Ans &= 总情况数 - |f(1)| - |f(2)| + |f(1) \cap f(2)| \\ &= 总情况数 - |f(1)| - |f(2)| + \left( |f( 1,2)| + |f(2, 1)| - |f(1,2) \cap f(2, 1)|\right) \\ &= \cdots\end{align*} \]

以此类推,每次拆开最后一项,那么最终得到:

\[\begin{align*}Ans &= 总情况数 - |f(1)| - |f(2)| + |f(1,2)| + |f(2,1)| - |f(1,2,1)| - |f(2,1,2)| + \cdots \\ &= 总情况数 + \sum _ s (-1) ^ {|s|} \times |f(s)|\end{align*} \]

也就是说我们需要算出所有的 \(f(s)\),其中 \(s\) 是一个 \(1\)、\(2\) 交替的序列。

Part 3

依旧从简单入手,我们考虑从 \(f(1,2)\) 开始算,并推广。

我们考虑刻画这种情形,如下图:

这是一个先经过 \(l_1\) 后经过 \(l_2\) 的路径,类似地,(但是注意要倒着来,可以解释为“生成”操作的逆)我们先将其对 \(l_2\) 对称(绿色),再对 \(l_1\) 对称(粉色),得到一个从原点到 \(C'\)(\(C'\) 为 \(C\) 关于 \(l_1\) 的对称点)的路径,这也是好算的。

那么可以推广出一个 \(f(s)\) 的算法,即我们倒序枚举 \(i\),将 \(B\) 关于 \(l_{s_i}\) 翻折。这样得到最后的点后用 \(\binom {x+y} x\) 即可算出。

Part 4

总结一下算法流程。

因为我们算 \(f(s)\) 要从后往前算,那么我们干脆直接从后往前来拆。

我们分两种情况,分别是 \(s\) 序列最后一位是 \(1\) 或 \(2\)。

对于最后一位是 \(1\) 的所有 \(s\):

  • 我们将当前点按照 \(l_1\) 翻折,得到的点 \((x,y)\),将 \((x,y)\) 的贡献乘上系数 \(-1\) 加入答案。

  • 我们再将其按照 \(l_2\) 翻折,得到的 \((x',y')\) 贡献,乘上系数 \(1\) 加入答案。

  • 在 \((x,y)\) 不到第二、三、四象限的条件下重复以上步骤。

(系数是由 Part 2 的容斥式子中 \(|s|\) 决定的)

这样我们可以扫一遍算出所有最后一位是 \(1\) 的 \(s\) 的贡献。

那么对于最后一位是 \(2\) 的也类似,只是交换 \(l_1,l_2\) 的位置。

Part 5

分析一下复杂度,发现我们的复杂度由翻折的次数决定。

我们发现,每次翻折都至少使得 \(\min(x,y)\) 减少 \(1\),那么复杂度是 \(O(\min(x,y))\)。

相关新闻

  • 企业信息化建设的钱都花在哪儿了?
  • 解释这些区块链核⼼概念:区块、交易、Merkle Tree、共识机制(PoW、PoS)、Gas Fee 原理2
  • 一次XFS死锁问题分析

最新新闻

  • 【GD32F427开发板试用】+ 从GPIO到USB:GD32F427V-START例程实战解析
  • 企业RAG知识库落地,应如何设计实现?
  • 2026 年 6 月 19 日北京东城区奢侈品名表回收核心门店专业测评 - 奢侈品回收
  • 2026湖北现代科技学校招生政策详解:报名条件+录取分数线+资助政策(免学费2000元/年+助学金6900元) - 速递信息
  • 物联网Lora模块串口通讯实战:数据收发与指令解析
  • 青岛名包回收避坑指南,认准资质齐全合扬门店保障交易安全 - 奢侈品交易观察员

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号