csp2021括号序列

主要方法:用多个数组表示不同状态,同时维护两个dp数组

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 500 + 10, mod = 1e9 + 7;
int n, k, f[N][N], g[N][N];
void add(int &x, int y) {
   x = (x + y) % mod; 
}
int sub(int x, int y) {
    return (x + mod - y) % mod;
}
signed main(){
    cin >> n >> k;
    string s; cin >> s;
    int len = s.size() - 1;
    s = '1' + s;
    for (int l = n - 1; l >= 1; l--) {
        if (s[l] != '(' && s[l] != '?') continue;
        for (int r = l + 1; r <= n; r++) {
            if (s[r] != ')' && s[r] != '?') continue;
            // ()
            if (l == r - 1) add(f[l][r], 1);
            // (S)
            for (int i = l + 1; i <= r - 1; i++) {
                if(s[i] != '*' && s[i] != '?') break;
                if (i == r - 1 && l + k + 1 >= r) add(f[l][r], 1);
            }
            // (SA)
            for (int i = l + 1; i < r - 1 && i <= k + l; i++) {
                if(s[i] != '*' && s[i] != '?') break;
                add(f[l][r], g[i + 1][r - 1]);
            }
            // (AS)
            for (int i = r - 1; i > l && i >= r - k; i--) {
                if(s[i] != '*' && s[i] != '?') break;
                add(f[l][r], g[l + 1][i - 1]);
            }
            // (A)
            add(f[l][r], g[l + 1][r - 1]);
            // f
            add(g[l][r], f[l][r]);
            // AB
            for (int x = l + 1; x < r; x++) add(g[l][r], f[l][x] * g[x + 1][r] % mod);
            // ASB
            vector<int> sum(r - l + 5, 0);
            for (int i = l + 1; i <= r; i++) 
                sum[i - l] = (sum[i - l - 1] + g[i][r]) % mod; 
            int rr = 0;
            //  cout << f[l][r] << ' ' << g[l][r] << ' ' << l << r <<endl; 
            for (int x = l + 1; x < r; x++) {
                if (rr <= x) rr = x + 1;
                if (s[rr] != '?' && s[rr] != '*')continue;
                if (rr==r) continue;
                while(rr + 1 < r && (s[rr + 1] == '?' || s[rr + 1] == '*') && rr + 1 - x <= k) rr++;
                add(g[l][r], f[l][x] * sub(sum[rr + 1 - l], sum[x + 1 - l]) % mod);
                // cout <<"?" << rr <<sum[rr + 1 - l]<<' '<< sum[x + 1 - l]<<sub(sum[rr + 1 - l], sum[x + 2 - l])<<endl;
            }
        }
    }
    // cout<<f[1][n]<<endl;
    cout << g[1][n] << endl;
}
posted @ 2024-12-03 13:50  lyrrr  阅读(5)  评论(0编辑  收藏  举报