区间dplc730及其扩展问题题解

Posted hans774882968

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间dplc730及其扩展问题题解相关的知识,希望对你有一定的参考价值。

传送门

lc730题解

又💧一篇

作者:hans774882968以及hans774882968

原问题要求去重,增加了分析的难度。若去掉该要求,则可以直接基于容斥原理来得到转移方程。仍然采用定义:dp[L][R]s[L~R]中的回文子序列个数。仍然分s[L] == s[R]和不相等来讨论。

  • 不相等,则两端无法同时参与构建回文子序列,仍然根据容斥原理,得dp[L][R] = dp[L + 1][R] + dp[L][R - 1] - dp[L + 1][R - 1]
  • 相等,则在容斥原理式子的基础上加上两端同时参与的方案数。对于t ∈ dp[L+1][R-1],加上两端的字符ch,都合法。再加上ch + ch,故为dp[L][R] = dp[L + 1][R] + dp[L][R - 1] + 1
class Solution:
    def bf(self, s: str) -> int:
        n = len(s)
        ans = 0
        for S in range(1, 1 << n):
            t = ""
            for i in range(n):
                if S >> i & 1:
                    t += s[i]
            if t == t[::-1]:
                ans += 1
        return ans

    def countPalindromicSubsequences(self, s: str) -> int:
        n, C, mod = len(s), 4, int(1e9) + 7
        dp = [[0] * n for _ in range(n)]
        for i in range(n):
            dp[i][i] = 1
        for L in range(n - 1, -1, -1):
            for R in range(L + 1, n):
                if s[L] == s[R]:
                    dp[L][R] = (dp[L + 1][R] + dp[L][R - 1] + 1) % mod
                else:
                    dp[L][R] = ((dp[L + 1][R] + dp[L][R - 1] -
                                dp[L + 1][R - 1]) % mod + mod) % mod
        if n <= 20:
            assert dp[0][n - 1] == self.bf(s)
        return dp[0][n - 1]


def test1(s):
    for i in range(1, 8):
        for it in itertools.product(*(['abcd'] * i)):
            v = "".join(it)
            s.countPalindromicSubsequences(v)

以上是关于区间dplc730及其扩展问题题解的主要内容,如果未能解决你的问题,请参考以下文章

区间和与线段树

SDOI2016 征途 题解

WD与地图题解

蓝桥杯AcWing 题目题解 - 二分与前缀和差分

区间DP总结

Codeforces Round #730 div.2 A-E题解