1. 程式人生 > 實用技巧 >阿里雲搭建簡單伺服器

阿里雲搭建簡單伺服器

CF149D Coloring Brackets

題目連結

​ 匹配DP。

​ 用\(f[l][r][0/1/2][0/1/2]\)表示在區間\([l, r]\)中,\(l\)位置的括號不染色/染紅色/染藍色,\(r\)位置的括號不染色/染紅色/染藍色的方案數。

​ 考慮轉移:

​ 當\(l + 1 == r\)的時候,表示邊界

f[l][r][0][1] = f[l][r][0][2] = f[l][r][1][0] = f[l][r][2][0] = 1;

​ 當\(l\)\(r\)括號匹配的時候,

dfs(l + 1, r - 1);
for(int i = 0;i <= 2; i++) 
            for(int j = 0;j <= 2; j++) {
                if(i != 1) (f[l][r][1][0] += f[l + 1][r - 1][i][j]) %= mod;
                if(i != 2) (f[l][r][2][0] += f[l + 1][r - 1][i][j]) %= mod;
                if(j != 1) (f[l][r][0][1] += f[l + 1][r - 1][i][j]) %= mod;
                if(j != 2) (f[l][r][0][2] += f[l + 1][r - 1][i][j]) %= mod;
            }

​ 當\(l\)\(r\)括號不匹配的時候,

dfs(l, match[l]); dfs(match[l] + 1, r); //match[l]表示與l匹配的右括號位置
        for(int i = 0;i <= 2; i++) 
            for(int j = 0;j <= 2; j++) 
                for(int p = 0;p <= 2; p++) 
                    for(int q = 0;q <= 2; q++) {
                        if((j == 1 && p == 1) || (j == 2 && p == 2)) continue;
                        (f[l][r][i][q] += 1ll * f[l][match[l]][i][j] * f[match[l] + 1][r][p][q] % mod) %= mod;
                    }

​ 完整程式碼:

#include <bits/stdc++.h>
    
using namespace std;
    
inline long long read() {
    long long s = 0, f = 1; char ch;
    while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
    for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
    return s * f;
}
    
const int N = 705;
const long long mod = 1000000007;
char ch[N];
int len, top, sta[N], match[N];
long long ans, f[N][N][3][3];

void dfs(int l, int r) {
    if(l + 1 == r) {
        f[l][r][0][1] = f[l][r][0][2] = f[l][r][1][0] = f[l][r][2][0] = 1;
        return ;
    }
    else if(match[l] == r) {
        dfs(l + 1, r - 1);
        for(int i = 0;i <= 2; i++) 
            for(int j = 0;j <= 2; j++) {
                if(i != 1) (f[l][r][1][0] += f[l + 1][r - 1][i][j]) %= mod;
                if(i != 2) (f[l][r][2][0] += f[l + 1][r - 1][i][j]) %= mod;
                if(j != 1) (f[l][r][0][1] += f[l + 1][r - 1][i][j]) %= mod;
                if(j != 2) (f[l][r][0][2] += f[l + 1][r - 1][i][j]) %= mod;
            }
    }
    else {
        dfs(l, match[l]); dfs(match[l] + 1, r);
        for(int i = 0;i <= 2; i++) 
            for(int j = 0;j <= 2; j++) 
                for(int p = 0;p <= 2; p++) 
                    for(int q = 0;q <= 2; q++) {
                        if((j == 1 && p == 1) || (j == 2 && p == 2)) continue;
                        (f[l][r][i][q] += 1ll * f[l][match[l]][i][j] * f[match[l] + 1][r][p][q] % mod) %= mod;
                    }
    }
}

int main() {

    cin >> ch + 1;
    len = strlen(ch + 1);
    
    for(int i = 1;i <= len; i++) {
        if(ch[i] == '(') 
            sta[++top] = i;
        if(ch[i] == ')') 
            match[sta[top--]] = i;
    }
    dfs(1, len);
    
    for(int i = 0;i <= 2; i++) 
        for(int j = 0;j <= 2; j++) 
            (ans += f[1][len][i][j]) %= mod;
    printf("%lld", ans);
    
    return 0;
}