zoukankan      html  css  js  c++  java
  • CF1015F Bracket Substring(动态规划)

    CF1015F Bracket Substring

    这题一眼GT考试

    题意: 求有多少种合法的括号序列要求字符串S是其字串

    数据范围大概是一个(Theta(n^3))的算法

    从前往后填括号, 设(F[i][j][k])表示填到第(i)位, "和"为(j), 匹配了(S k)位, 其中和的定义为将左括号看做1, 右括号看作-1, 一个合法的括号序列的前缀和总大于等于零且本身的和为零(一个左括号一定匹配一个右括号)

    (dp)时只需枚举下一位填('(')(')')即可, 但要注意的是匹配(S)串时从第(k)位不匹配不是直接重新从0开始匹配而是求出它的(kmp)数组, 找到上一个(border), 可以参考代码

    #pragma GCC optimize(2)
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define ll long long
    using namespace std;
    
    template <typename T>
    void read(T &x) {
        x = 0; bool f = 0;
        char c = getchar();
        for (;!isdigit(c);c=getchar()) if (c=='-') f=1;
        for (;isdigit(c);c=getchar()) x=x*10+(c^48);
        if (f) x=-x;
    }
    
    template <typename T>
    void write(T x) {
        if (x < 0) putchar('-'), x = -x;
        if (x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    
    const int N = 305;
    char s[N];
    ll n, m;
    int g[N][2], nxt[N];
    
    void KMP(void) {
    	int j = nxt[1] = 0;
    	for (int i = 2;i <= m; i++) {
    		while (j && s[i] != s[j+1]) j = nxt[j];
    		if (s[i] == s[j+1]) j++;
    		nxt[i] = j;
    	}
    	for (int i = 0;i < m; i++) {
    		int k = i, p = i;
    		while (k && s[k+1] != '(') k = nxt[k];
    		while (p && s[p+1] != ')') p = nxt[p];
    		if (s[k+1] == '(') k++;
    		if (s[p+1] == ')') p++;
    		g[i][1] = k, g[i][0] = p;
    	}
    	g[m][0] = g[m][1] = m;
    }
    
    const int P = 1e9+7;
    ll f[N][N][N];
    
    inline void add(ll &x, ll y) {
    	x += y; if (x >= P) x -= P;
    }
    
    int main() {
    	read(n); int al = n << 1;
    	scanf ("%s", s + 1);
    	m = strlen(s + 1);
    	KMP();
    	f[0][0][0] = 1;
    	for (int i = 0; i < al; i++) {
    		for (int j = 0; j <= n; j++) {
    			for (int k = 0; k <= m; k++) {
    				ll t = f[i][j][k];
    				if (j) add(f[i+1][j-1][g[k][0]], t);
    				add(f[i+1][j+1][g[k][1]], t);
    			}
    		}
    	}
    	cout << f[al][0][m] << endl;
    	return 0;
    }
    
  • 相关阅读:
    Xposed模块开发基本方法记录
    Win8.1下运行环境/配置问题解决方案总结
    wordpress安装记录
    编译时:virtual memory exhausted: Cannot allocate memory
    Support for AMD usage of jwplayer (require js)
    UC 浏览器远程调试手机web网页记录
    手机浏览器页面点击不跳转(Android手机部分浏览器) 浏览器双击放大网页 解决
    aes 加密,解密(2)
    aes 加密,解密
    ionic 安装步骤
  • 原文地址:https://www.cnblogs.com/Hs-black/p/12295083.html
Copyright © 2011-2022 走看看