LC 100136. 统计好分割方案的数目

https://leetcode.cn/problems/count-the-number-of-good-partitions/description/

如果是用前向搜索的话,好像枚举状态会比较多,所以比较适合从后往前搜索。

我这里写个一个DP状态方程,看的出来似乎是需要保持另外一个数组来进行累计。

对于第一个条件,还有一个附加条件,就是这个 i 必须是最开始的下标,比如 `[1,5,1,5,8]` 为例:

如果我们要求解到有效的 `last` 的话,需要多轮枚举。还是以 `[1,5,1,5,8]` 为例:

class Solution:
    def numberOfGoodPartitions(self, nums: List[int]) -> int:
        # dp[i] = dp[j+1] + .. + dp[n-1]  where nums[i] = nums[j].
        # acc[i] = acc[i] + acc[i+1] + ... + acc[n-1]
        n = len(nums)

        direct = {}
        for i in range(n):
            direct[nums[i]] = i

        last = [-1] * n
        visited = [0] * n
        for i in range(n):
            if visited[i]: continue
            j = i
            end = direct[nums[i]]
            while j < end:
                end = max(direct[nums[j]], end)
                j += 1
            last[i] = end
            for k in range(i, j + 1):
                visited[k] = 1

        MOD = 10 ** 9 + 7
        # print(last)
        dp = [0] * n
        acc = [0] * (n + 1)
        acc[-1] = 1
        for i in reversed(range(n)):
            p = last[i]
            if p == -1:
                dp[i] = 0
            else:
                dp[i] = acc[p + 1]
            acc[i] = (acc[i + 1] + dp[i]) % MOD
        return dp[0]