1 条题解
-
0
1. 题意理解
我们有一个数字串 ,长度 。
定义 表示把整数 拆分成若干个 的数的和的方案数(顺序不同视为不同方案)。
这其实就是:用 来组成 的有序拆分的个数。例如 时,,因为:
的定义:
把数字串 任意切成若干段(每段是一个数,允许前导零),把每段对应的整数加起来得到 ,然后计算 ,并对所有切分方案求和。例如 "123":
- 切分 "" → ,求
- 切分 "" → ,求
- 切分 "" → ,求
- 切分 "" → ,求
2. 先分析 的计算
是有序拆分成 的方案数。
$$f(k) = f(k-1) + f(k-2) + \dots + f(k-m), \quad k \ge 1 $$
这是一个经典的递推问题:其中 当 。
解释:最后一步可以放 ,所以从 等转移过来。
因为 ,这个递推是线性的,可以用矩阵快速幂来求 对 取模的值。
但 可能很大(字符串长度 ,数字总和最大是 ?不对,切分后加起来可能很大,因为一段可能是一个几百位数)。
例如 全是 ,长度 ,那么 最大可能是这个 位数本身,即 量级,不可能直接算 。
3. 关键观察
的递推是线性递推,模 下, 在 很大时可以用矩阵快速幂计算,但 可能极大(几百位十进制数),直接对 做快速幂不行。
但是,线性递推在模 下具有周期性,并且 可以表示成矩阵 的 次幂的形式。设:
$$F_k = \begin{bmatrix} f(k) & f(k-1) & \dots & f(k-m+1) \end{bmatrix}^T $$那么:
其中 是 矩阵:
$$M = \begin{bmatrix} 1 & 1 & 0 & 0 & \dots & 0 \\ 1 & 0 & 1 & 0 & \dots & 0 \\ 1 & 0 & 0 & 1 & \dots & 0 \\ \vdots & & & & \ddots & \vdots \\ 1 & 0 & 0 & \dots & 0 & 1 \\ 1 & 0 & 0 & \dots & 0 & 0 \end{bmatrix} $$(第一列全是 ,次对角线下方的 的位置对应递推)
更准确地说,对于 :
$$M_{1,j} = 1 \ (1 \le j \le m),\quad M_{i,i-1} = 1 \ (2 \le i \le m),\ 其余为 0 $$检查一下:
对应第一行全 。
对应 。
于是:
其中 。
所以 (因为 )。
4. 问题转化为:对所有切分方案,求 的 元素之和
设一种切分方式得到的各段数值为 ,则 。
我们要的是:
$$\sum_{\text{partition}} (M^{a_1 + a_2 + \dots + a_t})_{1,1} $$
注意矩阵幂的性质:
。所以:
$$M^{a_1 + \dots + a_t} = M^{a_1} \cdot M^{a_2} \cdots M^{a_t} $$我们要求的是这个乘积的 元素的和。
5. 动态规划
设 表示考虑前 个字符的所有切分方式下,矩阵乘积的和(一个 矩阵)。
初始:(单位矩阵)。
转移:
$dp[i] = \sum_{j=0}^{i-1} dp[j] \cdot M^{\text{num}[j+1:i]}$其中 是子串 对应的整数。
最终答案 = 的 元素。
因为 ,直接做是 会太大(矩阵乘法 但 很小,主要是 大)。
需要优化: 可能很大,但 是在模 下,且指数可对矩阵的阶取模?
矩阵在模 下的阶至多是 量级,但 很大,不能直接降指数。
6. 大指数矩阵快速幂
对于 ,其中 是几百位十进制数,我们可以用十进制矩阵快速幂:
预处理 ,然后按数字位乘起来。这样计算 是 ,len 是 num 的位数。
7. 最终算法
- 预处理 的 次幂,。
- DP:
对于 :
(矩阵)
对于 :
= 子串 对应的整数(可能很大,但我们用十进制矩阵快速幂算 )
- 输出 。
复杂度: 还是大,但 时 ,不可行。
需要优化:注意到从 到 , 是 $num_{j+1,i} = num_{j+1,i-1} \times 10 + (S[i] - '0')$。
我们可以从小到大枚举 ,同时维护 ,这样不用每次都做十进制快速幂。
具体:
对每个 ,维护 ,当 增加时,。
但 还是需要做矩阵快速幂( 次幂很快,因为 小)。这样每步是 ,总 ,可过。
8. 总结
算法步骤:
- 定义 转移矩阵 。
- 是 矩阵,表示前 个字符的所有切分对应的矩阵乘积之和。
- 初始 。
- 对 :
- 初始化 为零矩阵。
- 对 :
- 计算 ,利用上一步的 做 。
- 更新 。
- 输出 。
- 1
信息
- ID
- 5037
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者