力扣1977. 划分数字的方案数

427 阅读2分钟

这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战

1977. 划分数字的方案数

截屏2021-08-28 下午1.22.40.png

思路分析

对于一道很明显的动态规划题,相对于代码,更加重要的是写出状态转移方程的思路。在写状态转移方程之前,需要明确状态表示。

  • 数字要求非递减,以及没有前导0,这很明显是过滤的条件。暂且记下稍后会用到。
  • 假设num=“327154”,在我们已经划分好327的情况下,添加1以后,方案会发生什么变化呢?
    • 首先,1是不可以自己成为一个新单词的,因为无论是327还是27都大于1,不满足递减
    • 其次,使用327原方案一定能满足要求,为最后一个数字增加一位,一定会使这个数字更大,所以不会影响结果
    • 最后,我们需要考虑32, 71。这类使用1和其他字母联合在一起出现的新方案,但其本质上可以理解为32后面新增个71,因此我们不能单纯从数据的长度来进行动态规划,还必须要考虑某给定长度下最后一个元素的位置

这个时候答案基本就出来一半了

dp[i][j] 表示长度为j的字符串,最后一个整数的起点为i的情况,

  • 我们可以根据dp[i][j]判断出末尾数字为j - i 位
  • 由于dp[i][j]的末尾数字从i开始,因此他的方案一定来自于dp[k][i - 1], 其中如果i - 1 - k> j - i,那么一定非法 如果i - 1 - k < j - i, 那么一定合法。 如果 i - 1 - k = j - i,对于这种方式我们需要比较两者的大小。(可以通过最大前缀的长度来剪枝)
    • 如果最后一个元素大,则合法。
  • 结果为dp[k][n] (k为任意值)的和