首页 > 其他 > 详细

CF149D Coloring Brackets 【动态规划】

时间:2021-05-27 18:23:18      阅读:18      评论:0      收藏:0      [点我收藏+]

区间dp,dp[i][j][l][r] 表示区间i到j里,左端点为l颜色,右端点为r颜色的染色方案数,强制不合法的区间的值为0

转移只会有两种:

当这个的两个端点为配对的连个括号时,直接把区间i+1,j-1的答案拿过来用

当两个端点不配对时,肯定,这段区间肯定是由多个小的区间组成的,但我们并不关心有多少个,只要把大区间从一个合法的位置割开然后计算答案就行了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#define gi get_int()
#define int long long
const int MAXN = 1000, MOD = 1e9 + 7;
int get_int()
{
  int x = 0, y = 1;
  char ch = getchar();
  while (!isdigit(ch) && ch != ‘-‘)
    ch = getchar();
  if (ch == ‘-‘)
    y = -1, ch = getchar();
  while (isdigit(ch))
    x = x * 10 + ch - ‘0‘, ch = getchar();
  return x * y;
}

int dp[MAXN][MAXN][3][3], pos[MAXN];

signed main()
{
  freopen("code.in", "r", stdin);
  freopen("code.out", "w", stdout);

  std::string str;
  std::cin >> str;
  int n = str.size();
  std::stack<int> st;
  for (int i = 0; i < n; i++) {
    if (str[i] == ‘(‘) st.push(i);
    else {
      pos[i] = st.top();
      pos[st.top()] = i;
      st.pop();
    }
  }
  for (int i = 1; i < n; i++)
    if (str[i] == ‘)‘ && str[i - 1] == ‘(‘) {
      dp[i - 1][i][0][2] = dp[i - 1][i][1][2] = dp[i - 1][i][2][0] = dp[i - 1][i][2][1] = 1;
    }
  for (int size = 4; size <= n; size += 2) {
    for (int i = 0; i <= n - size; i++) {
      int j = i + size - 1;
      if (str[i] != ‘(‘ || str[j] != ‘)‘)
        continue;
      if (pos[i] == j) {
        (dp[i][j][0][2] += dp[i + 1][j - 1][1][2] + dp[i + 1][j - 1][2][0] + dp[i + 1][j - 1][2][1] + dp[i + 1][j - 1][1][0] + dp[i + 1][j - 1][2][2] + dp[i + 1][j - 1][1][1]) %= MOD;
        (dp[i][j][1][2] += dp[i + 1][j - 1][0][2] + dp[i + 1][j - 1][2][0] + dp[i + 1][j - 1][2][1] + dp[i + 1][j - 1][0][1] + dp[i + 1][j - 1][2][2] + dp[i + 1][j - 1][0][0]) %= MOD;
        (dp[i][j][2][0] += dp[i + 1][j - 1][2][1] + dp[i + 1][j - 1][0][2] + dp[i + 1][j - 1][1][2] + dp[i + 1][j - 1][0][1] + dp[i + 1][j - 1][2][2] + dp[i + 1][j - 1][1][1]) %= MOD;
        (dp[i][j][2][1] += dp[i + 1][j - 1][2][0] + dp[i + 1][j - 1][0][2] + dp[i + 1][j - 1][1][2] + dp[i + 1][j - 1][1][0] + dp[i + 1][j - 1][2][2] + dp[i + 1][j - 1][0][0]) %= MOD;
      } else {
        int mid = pos[i];
        for (int colorL0 = 0; colorL0 < 3; colorL0++)
          for (int colorR0 = 0; colorR0 < 3; colorR0++)
            for (int colorL1 = 0; colorL1 < 3; colorL1++)
              for (int colorR1 = 0; colorR1 < 3; colorR1++) {
                if (colorR0 == colorL1 && colorR0 != 2) continue;
                (dp[i][j][colorL0][colorR1] += dp[i][mid][colorL0][colorR0] * dp[mid + 1][j][colorL1][colorR1]) %= MOD;
              }
      }
    }
  }
  int ans = 0;
  for (int colorL0 = 0; colorL0 < 3; colorL0++)
    for (int colorR0 = 0; colorR0 < 3; colorR0++) {
      (ans += dp[0][n - 1][colorL0][colorR0]) %= MOD;
    }
  std::cout << ans;
  return 0;
}

CF149D Coloring Brackets 【动态规划】

原文:https://www.cnblogs.com/enisP/p/14817986.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!