730.cc 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. using std::string;
  5. using std::vector;
  6. using std::cout; using std::endl;
  7. class Solution {
  8. public:
  9. int countPalindromicSubsequences(string S) {
  10. int n = S.length();
  11. vector<vector<long>> dp(n, vector<long>(n, 0));
  12. for (int i = 0; i < n; i++)
  13. dp[i][i] = 1;
  14. for (int len = 1; len < n; len++) {
  15. for (int i = 0; i + len < n; i++) {
  16. int j = i + len;
  17. if (S[i] == S[j]) {
  18. dp[i][j] = 2 * dp[i + 1][j - 1];
  19. int l = i + 1, r = j - 1;
  20. for (; l <= r && S[l] != S[i]; l++);
  21. for (; l <= r && S[r] != S[j]; r--);
  22. if (l == r)
  23. dp[i][j] += 1;
  24. else if (l > r)
  25. dp[i][j] += 2;
  26. else
  27. dp[i][j] -= dp[l + 1][r - 1];
  28. } else {
  29. dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1];
  30. }
  31. dp[i][j] = dp[i][j] % MOD;
  32. }
  33. }
  34. return dp[0][n - 1];
  35. }
  36. private:
  37. static constexpr long MOD = 1000000007;
  38. };
  39. // Input:
  40. // S = 'abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba'
  41. // Output: 104860361
  42. // bccb
  43. // len 0:
  44. // len 1: b c
  45. // len 2: bb cc
  46. // len 3: bcb
  47. // len 4: bccb
  48. // dp[i][j] means different palindroms count between i and j
  49. // loop len, i, j
  50. // init:
  51. // dp[i][i] = 1
  52. // s[i] == s[j]:
  53. // CASE1: b ccbcc b -> +"bb"
  54. // 2 * count(ccbcc) + 1
  55. // CASE2: b c b -> +"b" +"bb"
  56. // 2 * count(c) + 2
  57. // CASE3: b ca b -> +"b" +"bb"
  58. // 2 * count(ca) + 2
  59. // CASE4: b bcab b -> -"bcb" -"bab"
  60. // 2 * count(bcab) - count(ca)
  61. // s[i] != s[j]:
  62. // dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1]
  63. int main() {
  64. Solution* sol = new Solution;
  65. string input;
  66. input = "addd";
  67. cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 4 << endl;
  68. input = "bccb";
  69. cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 6 << endl;
  70. input = "abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba";
  71. cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 104860361 << endl;
  72. input = "baaddaaabaddccbbbdcbcccbdbdabdabdbadabddbbcbbcabbccdaccdbcbbcdcdbaadbcadacabcaaaadbcaddbbacddcdabaadcacacdcabaadacadcccdcbbcdabdcdacaacdcdbdacbdbcdcbaddaccabaaaabcadacdaddbcccbcdbadbdddaaabbdbdbcbcdab";
  73. cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 431300010 << endl;
  74. input = "bdccbdbdcaacaadbdacaadabbdaababacbdbadaccccbbbccbdbddcacdbbcdaaababddadbbcabaddbbaabcdacdcddcbacdcadddbaadcbbccdcbdcaaabcbddacaccadacdcadacadccabdbadcdabaaccbcabbacdcbbbabddbcccbcbcddacaccabbabccdbbabacadbbdbcccbddaaadcdaddcccddaacbddabddabadbcbaadcaddbdccabaddcccdccbacaccccbcdccacbabddcbcbbbdbbddaabbcaddbddddaacbbccbcdbadacccbadbccdddadcbacbbdcabcbdbbaabcdcbdacabacdccdaabcbbddbdddcacdbdccbbabbaccdcbabcdacdabdddaddacdbddabcbbbdcccacbdadddbbdbcabccadbcbadddcbcddaababcabbbcbbabadaddabcbdacaadcababcbacadcdabcdbddadaadddddbaaacddaacadcdbaaacbacaabdabccbacabbabddacddcdacdcddbacbddbdcadcddabdadcdbcbbcadbcdabbbbdcdadadbbcadbcbbcccccabdaabcdacbdbcadabcdbaaaaacdaaabcdcaabddcacdcacabbaadbdbcbaaabadbdadadaccddacababbdcbaaaccaabbdaddadcabaabbdaadadcabcabbdbbdccbabbbabbcbcbdcacccbdbabdbaadccdaddaddaadadccabdcbbbccacbbaaabccaccdcabbbddbdbbacdaabbdcdacbdddbacbadccabbbdbbbdbdbcadcacddddcdbdcabccdccabaadbcbacaaababdddcbcdaaabaaabddbcabcbbcdddccdcbccbbccadccaaccccbdadcaacdcbcabacacadaabacddaadcccbcabdad";
  75. cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 739921586 << endl;
  76. return 0;
  77. }