fork download
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef pair<int, int> ii;
  7.  
  8. const int INF = 1e9;
  9. const ll LINF = 1e18;
  10.  
  11. const int MOD = 1e9 + 7;
  12. const int N = 5e2 + 5;
  13.  
  14. int n;
  15. string s;
  16.  
  17. int C[N][N]; // C[n][k] = Tổ hợp chập k của n
  18.  
  19. void precompute() {
  20. for (int i = 0; i <= n; i++) {
  21. C[i][0] = 1;
  22. for (int j = 1; j <= i; j++) {
  23. C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
  24. }
  25. }
  26. }
  27.  
  28. // dp(l, r) = Số cách để xoá hết đoạn [l, r] của xâu s
  29. int memo[N][N];
  30.  
  31. int dp(int l, int r) {
  32. if (l > r) return 1;
  33. if ((r - l + 1) % 2 == 1) return 0;
  34.  
  35. int& ans = memo[l][r];
  36. if (ans != -1) return ans;
  37.  
  38. ans = 0;
  39. int cnt = (r - l + 1) / 2; // Số bước cần dùng để xoá hết đoạn [l, r]
  40. for (int k = l + 1; k <= r; k++) { // s[k] sẽ đứng kề với s[l]
  41. if (s[l] == s[k]) {
  42. int cnt1 = (k - l - 1) / 2; // Số bước cần dùng để xoá hết đoạn [l + 1, k - 1]
  43. // Chỉ có thể xoá cặp (s[l], s[k]) sau khi đã xoá đoạn [l + 1, k - 1]
  44. // Chọn thời điểm xoá đoạn [l + 1, k - 1] và cặp (s[l], s[k])
  45. // Những thời điểm còn lại sẽ là xoá đoạn [k + 1, r]
  46. ans += 1ll * C[cnt][cnt1 + 1] * dp(l + 1, k - 1) % MOD * dp(k + 1, r) % MOD;
  47. ans %= MOD;
  48. }
  49. }
  50.  
  51. return ans;
  52. }
  53.  
  54. int main() {
  55. ios::sync_with_stdio(false);
  56. cin.tie(nullptr);
  57. cin >> s;
  58. n = s.size();
  59. s = ' ' + s;
  60.  
  61. precompute();
  62.  
  63. memset(memo, -1, sizeof memo);
  64.  
  65. cout << dp(1, n) << '\n';
  66. }
Success #stdin #stdout 0.01s 5280KB
stdin
aabccb
stdout
3