题目描述
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:
The length of S will be in the range [1, 1000].
Each character S[i] will be in the set {‘a’, ‘b’, ‘c’, ‘d’}.
思路
动态规划:dp[i][j]表示从i到j的字符串,能组成的回文串数目。
当S[i] == S[j]时,即首尾字符相同,由i+1到j-1的字符串中没有、有一个、多余一个首尾字符三种情况。
当S[i] != S[j]时,由dp[i+1][j] + dp[i][j-1]-dp[i+1][j-1]。
参考链接:https://www.jianshu.com/p/d1d4414c97d2
代码
class Solution {
public:
int countPalindromicSubsequences(string S) {
int n = S.length();
int MOD = 1e9+7;
vector<vector<int> > dp(n, vector<int>(n, 0));
for (int i=0; i<n; ++i) {
dp[i][i] = 1;
}
for (int l=2; l<=n; ++l) {
for (int i=0, j=i+l-1; j<n; ++i, ++j) {
if (S[i] == S[j]) {
dp[i][j] = dp[i+1][j-1] * 2;
int l = i+1;
int r = j-1;
while(l<=r && S[l] != S[i]) l++;
while(r>=l && S[r] != S[j]) r--;
if (l > r) {
dp[i][j] += 2;
}else if (l == r) {
dp[i][j] += 1;
}else {
dp[i][j] -= dp[l+1][r-1];
}
}else {
dp[i][j] = dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1];
}
dp[i][j] = (dp[i][j] < 0 ? dp[i][j] + MOD : dp[i][j]) % MOD;
}
}
return dp[0][n-1];
}
};