首先有一个很显然的状态:fi,j,k 表示走到 (i,j),乘积为 k 的方案数。
特别地,当 k=n 时表示乘积不小于 k 的方案数。
但是这样子是 O(rsn) 的。
如果我们把状态换一下,变成 fi,j,k 表示走到 (i,j),乘积至少乘 k 后不小于 n 的方案数。
看起来并没有什么变化……
但是,这样子的话,有用的 k 都形如 ⌈nd⌉。
类似数论分块,可以证明最多只有 O(√n) 种。
于是我们把有用的 k 重新标号(即离散化),然后跑 DP,同时滚动第一维(你要把第二维一起滚了也行 QwQ)。
这样子就得到了一个 O(rs√n) 的算法。
代码:
1 |
|