123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- #include <cstring>
- #include <iostream>
- #include <string>
- using std::string;
- using std::cout; using std::endl;
- // for 'a' ~ 'd'
- static const int X_MAX = 'd' - 'a';
- static const int N_MAX = 1000;
- static int dp[3][N_MAX][N_MAX][X_MAX + 1];
- class Solution {
- private:
- static const int MOD = 1000000007;
- public:
- int countPalindromicSubsequences(string S) {
- int n = S.size(), ans = 0, memset_size = sizeof(dp[0]);
- memset(dp, 0, sizeof(dp));
- for (int len = 1; len <= n; len++) {
- for (int sep = len - 1; sep < n; sep ++) {
- for (int i = 0; i + sep < n; i++) {
- int j = i + sep;
- int a = S[i] - 'a', b = S[j] - 'a';
- for (int x = 0; x <= X_MAX; x++)
- if (x != a && x != b && 1 < sep)
- dp[0][i][j][x] = dp[0][i + 1][j - 1][x];
- if (a == b) {
- if (len <= 2)
- dp[0][i][j][a] = 1;
- else
- for (int x = 0; x <= X_MAX; x++)
- dp[0][i][j][a] = (dp[0][i][j][a] + dp[2][i + 1][j - 1][x]) % MOD;
- } else if (0 < sep) {
- dp[0][i][j][a] = dp[0][i][j - 1][a];
- dp[0][i][j][b] = dp[0][i + 1][j][b];
- }
- }
- }
- for (int x = 0; x <= X_MAX; x++)
- ans = (ans + dp[0][0][n - 1][x]) % MOD;
- // Use scrolling array to save memory
- memcpy(dp[2], dp[1], memset_size);
- memcpy(dp[1], dp[0], memset_size);
- memset(dp[0], 0, memset_size);
- }
- return ans;
- }
- };
- // Input:
- // S = 'abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba'
- // Output: 104860361
- // bccb
- // len 0:
- // len 1: b c
- // len 2: bb cc
- // len 3: bcb
- // len 4: bccb
- // dp[1][0][0]['b'] = 1, dp[1][1][1]['c'] = 1, dp[1][2][2]['c'] = 1, dp[1][3][3]['b'] = 1
- // dp[len][i][j][x] means different palindroms count which start / end with 'x' between s[i] and s[j], length is len
- // loop len, sep, i
- // j = i + sep
- // for x != s[i] and x != s[j]:
- // dp[len][i][j][x] = dp[len][i + 1][j - 1][x]
- // s[i] == s[j] == a:
- // dp[len][i][j][a] = sum(dp[len - 2][i + 1][j - 1][every x])
- // s[i] == a, s[j] == b, a != b:
- // dp[len][i][j][a] = dp[len][i][j - 1][a],
- // dp[len][i][j][b] = dp[len][i + 1][j][b]
- int main() {
- Solution* sol = new Solution;
- string input;
- input = "addd";
- cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 4 << endl;
- input = "bccb";
- cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 6 << endl;
- input = "abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba";
- cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 104860361 << endl;
- input = "baaddaaabaddccbbbdcbcccbdbdabdabdbadabddbbcbbcabbccdaccdbcbbcdcdbaadbcadacabcaaaadbcaddbbacddcdabaadcacacdcabaadacadcccdcbbcdabdcdacaacdcdbdacbdbcdcbaddaccabaaaabcadacdaddbcccbcdbadbdddaaabbdbdbcbcdab";
- cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 431300010 << endl;
- input = "bdccbdbdcaacaadbdacaadabbdaababacbdbadaccccbbbccbdbddcacdbbcdaaababddadbbcabaddbbaabcdacdcddcbacdcadddbaadcbbccdcbdcaaabcbddacaccadacdcadacadccabdbadcdabaaccbcabbacdcbbbabddbcccbcbcddacaccabbabccdbbabacadbbdbcccbddaaadcdaddcccddaacbddabddabadbcbaadcaddbdccabaddcccdccbacaccccbcdccacbabddcbcbbbdbbddaabbcaddbddddaacbbccbcdbadacccbadbccdddadcbacbbdcabcbdbbaabcdcbdacabacdccdaabcbbddbdddcacdbdccbbabbaccdcbabcdacdabdddaddacdbddabcbbbdcccacbdadddbbdbcabccadbcbadddcbcddaababcabbbcbbabadaddabcbdacaadcababcbacadcdabcdbddadaadddddbaaacddaacadcdbaaacbacaabdabccbacabbabddacddcdacdcddbacbddbdcadcddabdadcdbcbbcadbcdabbbbdcdadadbbcadbcbbcccccabdaabcdacbdbcadabcdbaaaaacdaaabcdcaabddcacdcacabbaadbdbcbaaabadbdadadaccddacababbdcbaaaccaabbdaddadcabaabbdaadadcabcabbdbbdccbabbbabbcbcbdcacccbdbabdbaadccdaddaddaadadccabdcbbbccacbbaaabccaccdcabbbddbdbbacdaabbdcdacbdddbacbadccabbbdbbbdbdbcadcacddddcdbdcabccdccabaadbcbacaaababdddcbcdaaabaaabddbcabcbbcdddccdcbccbbccadccaaccccbdadcaacdcbcabacacadaabacddaadcccbcabdad";
- cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 739921586 << endl;
- return 0;
- }
|