动态规划

730. Count Different Palindromic

2018-04-19  本文已影响39人  Nancyberry

Description

Given a string S, find the number of different non-empty palindromic subsequences in S, and return that number modulo 10^9 + 7.

A subsequence of a string S is obtained by deleting 0 or more characters from S.

A sequence is palindromic if it is equal to the sequence reversed.

Two sequences A_1, A_2, ... and B_1, B_2, ... are different if there is some i for which A_i != B_i.

Example 1:

Input:
S = 'bccb'
Output: 6
Explanation:
The 6 different non-empty palindromic subsequences are 'b', 'c', 'bb', 'cc', 'bcb', 'bccb'.
Note that 'bcb' is counted only once, even though it occurs twice.

Example 2:

Input:
S = 'abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba'
Output: 104860361
Explanation:
There are 3104860382 different non-empty palindromic subsequences, which is 104860361 modulo 10^9 + 7.

Note:

Solution

DP (using 3D array), time

大开眼界的一道题,原来用3D DP好多事情都会迎刃而解。。

Let dp[x][i][j] be the answer for the substring S[i...j] where S[i] == S[j] == 'a'+x. Note that since we only have 4 characters a, b, c, d, thus 0 <= x < 4. The DP formula goes as follows:

Let n be the length of the input string S, The final answer would be dp[0][0][n-1] + dp[1][0][n-1] + dp[2][0][n-1] + dp[3][0][n-1] mod 1000000007.

考虑一下这种思路为什么2D DP是不够用的。假设dp[i][j]表示s[i...j]的palindrome sequence count,那么如果s[i] != s[j],dp[i][j] = dp[i + 1][j] + dp[i][j - 1]是错的,因为子问题会有重复解。只有再添加一维x,指定字符,每个子问题才是独立的。

好吧还是有点懵。。

class Solution {
    public int countPalindromicSubsequences(String s) {
        int n = s.length();
        int mod = 1000000007;
        int[][][] dp = new int[4][n][n];
        
        for (int i = n - 1; i >= 0; --i) {
            for (int j = i; j < n; ++j) {
                for (int k = 0; k < 4; ++k) {
                    char c = (char) ('a' + k);
                    
                    if (j == i) {
                        if (s.charAt(i) == c) {
                            dp[k][i][j] = 1;
                        }
                        continue;
                    }
                    
                    if (s.charAt(i) != c) {
                        dp[k][i][j] = dp[k][i + 1][j];
                    } else if (s.charAt(j) != c) {
                        dp[k][i][j] = dp[k][i][j - 1];
                    } else {
                        dp[k][i][j] = 2;
                        for (int x = 0; x < 4; ++x) {
                            dp[k][i][j] += dp[x][i + 1][j - 1];
                            dp[k][i][j] %= mod;
                        }
                    }
                }
            }
        }
        
        int res = 0;
        for (int k = 0; k < 4; ++k) {
            res += dp[k][0][n - 1];
            res %= mod;
        }
        
        return res;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读