看到这道题,最朴素的想法是用 DFS 求解。 显然这样搜出来的状态数量非常庞大,时间复杂度无法承受,考虑换用 DP 遍历所有状态。 这里有两个方法。 法一:(60pts) 设 $f_i$ 表示正整数 $i(i \in N^+)$ 分解后的最大乘积。 这种情况下乍一看似乎无法转移,因为有后效性,前面的数分解出 $k$ 那么后面就不能分解出 $k$ 了。 既然如此,可以尝试改变状态,多加几维限制。 思考后得出:设 $f(i,j)$ 表示正整数 $i(i \in N^+)$ 分解出的最大整数为 $j$ 时的最大乘积。 初始状态:$\forall i \in [0,n],f(0,i) = 1$ 状态转移方程:$f(i,j) = \max\limits_{k=1}^{j - 1} f(i - j,k) \times j$ 最终状态 $\max\limits_{i=0}^n f(n,i)$ 然而这样是 $O(N^3)$ 的,考虑优化。 令 $s(i,j) = \max\limits_{k=1}^j f(i,k)$ 则状态转移方程会变成:$f(i,j) = s(i - j,j - 1) \times j$ 初始 $\forall i \in [0,n],s(0,i) = 1$ 答案为 $s(n,n)$ 这样用 unsigned long long 可以过 $60%$ 的测试数据,但换成高精度则会出现一堆绿色的字母。 (upd:测试时发现,其实根据数学知识,每次转移的 $j$ 并不会太大,有兴趣的可以打个表把 $j$ 的范围缩小些,这样应该能直接 AC)
法二: (此方法我暂时给不出严谨的证明,只能感性理解给个大概意思) 再仔细想一想,难道这个 DP 就一定要二维吗? 再想一想,假设我们把 $i$ 分解为 $\{a_1,a_2\ldots a_k \}$,要枚举一个 $a_j(1\le j \le k)$ 进行状态转移。 不难发现,每个数字分别顺序的先后并不影响它对答案的贡献。 换言之,不论枚举的顺序如何,最优状态也一定会被遍历到。 基于此,我们令 $f_i$ 为 $i$ 分解的最优答案,用 bitset 或者 bool 数组记录一下哪些数字被选上了,转移一下就好了。 这个转移方程相当简单,就不写了,详情见 AC 代码。
题目618 [金陵中学2007] 最优分解方案
AAAAAAAAAA
14
2 条 评论
2022-05-20 21:16:44
|