730-slow.cc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include <cstring>
  2. #include <iostream>
  3. #include <string>
  4. using std::string;
  5. using std::cout; using std::endl;
  6. // for 'a' ~ 'd'
  7. static const int X_MAX = 'd' - 'a';
  8. static const int N_MAX = 1000;
  9. static int dp[3][N_MAX][N_MAX][X_MAX + 1];
  10. class Solution {
  11. private:
  12. static const int MOD = 1000000007;
  13. public:
  14. int countPalindromicSubsequences(string S) {
  15. int n = S.size(), ans = 0, memset_size = sizeof(dp[0]);
  16. memset(dp, 0, sizeof(dp));
  17. for (int len = 1; len <= n; len++) {
  18. for (int sep = len - 1; sep < n; sep ++) {
  19. for (int i = 0; i + sep < n; i++) {
  20. int j = i + sep;
  21. int a = S[i] - 'a', b = S[j] - 'a';
  22. for (int x = 0; x <= X_MAX; x++)
  23. if (x != a && x != b && 1 < sep)
  24. dp[0][i][j][x] = dp[0][i + 1][j - 1][x];
  25. if (a == b) {
  26. if (len <= 2)
  27. dp[0][i][j][a] = 1;
  28. else
  29. for (int x = 0; x <= X_MAX; x++)
  30. dp[0][i][j][a] = (dp[0][i][j][a] + dp[2][i + 1][j - 1][x]) % MOD;
  31. } else if (0 < sep) {
  32. dp[0][i][j][a] = dp[0][i][j - 1][a];
  33. dp[0][i][j][b] = dp[0][i + 1][j][b];
  34. }
  35. }
  36. }
  37. for (int x = 0; x <= X_MAX; x++)
  38. ans = (ans + dp[0][0][n - 1][x]) % MOD;
  39. // Use scrolling array to save memory
  40. memcpy(dp[2], dp[1], memset_size);
  41. memcpy(dp[1], dp[0], memset_size);
  42. memset(dp[0], 0, memset_size);
  43. }
  44. return ans;
  45. }
  46. };
  47. // Input:
  48. // S = 'abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba'
  49. // Output: 104860361
  50. // bccb
  51. // len 0:
  52. // len 1: b c
  53. // len 2: bb cc
  54. // len 3: bcb
  55. // len 4: bccb
  56. // dp[1][0][0]['b'] = 1, dp[1][1][1]['c'] = 1, dp[1][2][2]['c'] = 1, dp[1][3][3]['b'] = 1
  57. // dp[len][i][j][x] means different palindroms count which start / end with 'x' between s[i] and s[j], length is len
  58. // loop len, sep, i
  59. // j = i + sep
  60. // for x != s[i] and x != s[j]:
  61. // dp[len][i][j][x] = dp[len][i + 1][j - 1][x]
  62. // s[i] == s[j] == a:
  63. // dp[len][i][j][a] = sum(dp[len - 2][i + 1][j - 1][every x])
  64. // s[i] == a, s[j] == b, a != b:
  65. // dp[len][i][j][a] = dp[len][i][j - 1][a],
  66. // dp[len][i][j][b] = dp[len][i + 1][j][b]
  67. int main() {
  68. Solution* sol = new Solution;
  69. string input;
  70. input = "addd";
  71. cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 4 << endl;
  72. input = "bccb";
  73. cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 6 << endl;
  74. input = "abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba";
  75. cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 104860361 << endl;
  76. input = "baaddaaabaddccbbbdcbcccbdbdabdabdbadabddbbcbbcabbccdaccdbcbbcdcdbaadbcadacabcaaaadbcaddbbacddcdabaadcacacdcabaadacadcccdcbbcdabdcdacaacdcdbdacbdbcdcbaddaccabaaaabcadacdaddbcccbcdbadbdddaaabbdbdbcbcdab";
  77. cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 431300010 << endl;
  78. input = "bdccbdbdcaacaadbdacaadabbdaababacbdbadaccccbbbccbdbddcacdbbcdaaababddadbbcabaddbbaabcdacdcddcbacdcadddbaadcbbccdcbdcaaabcbddacaccadacdcadacadccabdbadcdabaaccbcabbacdcbbbabddbcccbcbcddacaccabbabccdbbabacadbbdbcccbddaaadcdaddcccddaacbddabddabadbcbaadcaddbdccabaddcccdccbacaccccbcdccacbabddcbcbbbdbbddaabbcaddbddddaacbbccbcdbadacccbadbccdddadcbacbbdcabcbdbbaabcdcbdacabacdccdaabcbbddbdddcacdbdccbbabbaccdcbabcdacdabdddaddacdbddabcbbbdcccacbdadddbbdbcabccadbcbadddcbcddaababcabbbcbbabadaddabcbdacaadcababcbacadcdabcdbddadaadddddbaaacddaacadcdbaaacbacaabdabccbacabbabddacddcdacdcddbacbddbdcadcddabdadcdbcbbcadbcdabbbbdcdadadbbcadbcbbcccccabdaabcdacbdbcadabcdbaaaaacdaaabcdcaabddcacdcacabbaadbdbcbaaabadbdadadaccddacababbdcbaaaccaabbdaddadcabaabbdaadadcabcabbdbbdccbabbbabbcbcbdcacccbdbabdbaadccdaddaddaadadccabdcbbbccacbbaaabccaccdcabbbddbdbbacdaabbdcdacbdddbacbadccabbbdbbbdbdbcadcacddddcdbdcabccdccabaadbcbacaaababdddcbcdaaabaaabddbcabcbbcdddccdcbccbbccadccaaccccbdadcaacdcbcabacacadaabacddaadcccbcabdad";
  79. cout << "actual: " << sol->countPalindromicSubsequences(input) << ", expected: " << 739921586 << endl;
  80. return 0;
  81. }