1 条题解
-
0
题意概述
给定一个 的矩阵,每个格子有一个正整数。
从左上角 走到右下角 ,每次只能向右或向下走。
定义一条路径的权值为路径上所有格子数值的乘积。
求权值不小于 的路径条数,答案对 取模。数据范围:,,矩阵元素 。
核心难点
- 路径数:从 到 的路径总数是 ,最大约 量级,无法直接枚举。
- 乘积增长:路径乘积可以极大( 个数乘积可能达到 ),无法直接存储。
- 约束:要求乘积 ,不是模意义下的比较,而是真实数值比较。
关键观察
由于 ,我们可以将“乘积不小于 ”转化为:
设路径乘积为 ,如果 ,则 ,否则 。
但这并不利于直接 DP。更直接的想法:
乘积 可以写成 形式,其中 等,但更常用技巧是:
转化为对数比较
取对数:。
条件 等价于 。由于 ,,路径最多 步,,可用浮点数或定点数存储。
但浮点数有精度问题,可能影响比较。
更稳健的方法:质因数分解
因为 ,可以将其质因数分解。
设 。
对于路径乘积 ,要满足 ,等价于:
对每个质因子 , 中 的指数不小于 中 的指数。不对! 因为即使每个质因子的指数都达到要求, 还可能比 小(比如其他质因子指数为0,但 有其他因子?实际上 包含所有 的质因子且指数足够时, 一定是 的倍数,所以 成立)。
更准确: 等价于 是 的倍数,且 ,但 可能不是整数?不,若 是 的倍数,则 自动成立。因此等价条件是:
是 的倍数。因为如果 是 的倍数,则 (因为矩阵元素是正整数)。
反过来,如果 ,不一定 是 的倍数。
所以这个转化是错的,不能直接等价。
正确转化:阈值法
设 的质因数分解为 。
对于 ,设它在 上的指数为 ,则: [ P \ge n \iff \prod p_i^{\max(0, f_i - e_i)} \times \text{(其他质因子幂)} \ge 1 ] 这并不好直接处理。常用技巧:
令 ,那么 等价于 。
但 可能很大,不能直接除。
动态规划状态设计
设 表示走到 时,路径乘积为 的路径数。
但 可能极大,不能直接存。注意到我们只关心 是否 ,以及 和 的比值在某种意义下的状态。
因为 ,我们可以考虑存储 模 的值?不行,模 不能判断大小。另一个思路:
令 ,并存储 的某些信息?
设 ,其中 ,且 。
那么 等价于 。
关键突破:状态为 (i, j, k)
定义 。
这里 是路径乘积。
的范围是 到 。
当 时,;否则 。转移时,从 到 或 , 乘以 ,对应 变为 。
这个转移可以写为: [ k' = \left\lfloor \frac{k}{a} \right\rfloor \quad \text{? 验证:} ] 因为 ,所以 [ k' = \left\lfloor \frac{n-1}{v \cdot a} \right\rfloor = \left\lfloor \frac{\lfloor \frac{n-1}{v} \rfloor}{a} \right\rfloor ] 这是正确的吗?
有公式 $\lfloor \frac{\lfloor x \rfloor}{a} \rfloor = \lfloor \frac{x}{a} \rfloor$ 当 是正整数时成立。
因此: [ k' = \left\lfloor \frac{k}{a} \right\rfloor ] 成立。因此,我们只需要 DP 状态 ,其中 , 是当前乘积。
初态:。
终态: 的路径数即为所求(因为 时 )。
DP 转移
设 表示走到 时 的路径数。
转移: [ dp[i+1][j][\lfloor k/a_{i+1,j} \rfloor] \ += dp[i][j][k] ] [ dp[i][j+1][\lfloor k/a_{i,j+1} \rfloor] \ += dp[i][j][k] ] 所有运算在模 下进行。
复杂度
状态数:,最大 ,显然太大。
需要优化。注意 的取值:
初始 ,每次转移 变为 , 是矩阵元素。
因为 , 会快速减小。
实际上, 的不同取值个数是 级别?
更准确:经过多次除以 (), 很快到 0。
但最坏情况 时 不变。
所以当 时, 不变,状态可能很多。
优化:只存有效状态
用 map 或 unordered_map 存储每个 对应的 的分布。
由于 取值是整数除法下递降的,不同 的数量是 级别(实际上更少,因为每次除以至少 1,且矩阵元素不一定全为 1)。但 ,,最坏情况 时 始终为 ,这样每个 只有一个 值,总状态数 ,可以接受。
如果 较大, 会迅速减小,状态更少。所以用 unordered_map 存 映射,总状态数可接受。
算法步骤
- 读入 和矩阵 。
- 初始化:。
- 按行、列顺序遍历 ,对每个 中的每个 :
- 向右走:,。
- 向下走:,。
- 最终答案 = 。
复杂度分析
每个 处 的不同取值个数是 级别,但实际更小。
总状态数约 ,最坏 ,可能稍大,但很多 会快速变为 0,实际运行可过。
总结
本题核心是将“乘积不小于 ”转化为 ,并利用整数除法的性质设计 DP 状态 ,转移为 。
通过只存储有效状态,将巨大的乘积范围压缩到 的整数,实现了可行解法。
复杂度 ,其中 是 的不同取值个数,实际运行较快。
- 1
信息
- ID
- 5741
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者