zoukankan      html  css  js  c++  java
  • CF1264D1 Beautiful Bracket Sequence (easy version)

    考虑在一个确定的括号序列中,我们可以枚举中间位置,按左右最长延伸出去的答案计算。

    我们很自然的思考,我们直接维护左右两边,在删除一些字符后能够延伸的最长长度。

    我们设(f_{i,j})(i)点合法删除向左延伸的最大长度。

    ( f_{i,j} = left{ egin{aligned} &f_{i - 1,j} (a[i] = ')' )\ &f_{i - 1,j - 1}(a[i] = ')' )\ &f_{i - 1,j} + f_{i - 1 ,j - 1} (a[i] = '?' )\ end{aligned} ight. )

    (g_{i,j})为向右延伸,则有同样的转移。

    (ans = sum_{i = 1}^nsum_{j = 1}^j f_{i,j} * g_{i + 1,j} * j)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long 
    #define N 2005
    #define mod 998244353
    
    char a[N];
    
    ll n;
    ll f[N][N],g[N][N];
    
    int main(){
    	scanf("%s",a + 1);
    	n = strlen(a + 1);
    	f[0][0] = 1;
    	for(int i = 1;i <= n;++i){
    		if(a[i] == '(' || a[i] == '?')
    		for(int j = 1;j <= n;++j)
    		f[i][j] = (f[i][j] + f[i - 1][j - 1]) % mod;
    		if(a[i] == ')' || a[i] == '?')
    		for(int j = 0;j <= n;++j)
    		f[i][j] = (f[i][j] + f[i - 1][j]) % mod;		
    	}
    	g[n + 1][0] = 1;
    	for(int i = n;i >= 1;--i){
    		if(a[i] == ')' || a[i] == '?')
    		for(int j = 1;j <= n;++j)
    		g[i][j] = (g[i][j] + g[i + 1][j - 1]) % mod;
    		if(a[i] == '(' || a[i] == '?')
    		for(int j = 0;j <= n;++j)
    		g[i][j] = (g[i][j] + g[i + 1][j]) % mod;
    	}	
    	ll ans = 0;
    	for(int i = 1;i <= n - 1;++i)
    	for(int j = 1;j <= n;++j)
    	ans = (ans + f[i][j] * g[i + 1][j] % mod * j % mod) % mod;
    	std::cout<<ans<<std::endl;
    }
    
  • 相关阅读:
    [Git & GitHub] 利用Git Bash进行第一次提交文件
    Linux下 Unison 实现文件双向同步
    Linux SSH使用公钥私钥实现免登陆
    SSH自动断开连接的原因
    hosts.deny 和hosts.allow 配置不生效
    bind启动时提示953端口被使用
    Linux查询系统配置常用命令
    Linux 查硬件配置
    BIND rndc—使用说明
    rndc 错误解决 和 远程配置
  • 原文地址:https://www.cnblogs.com/dixiao/p/15160071.html
Copyright © 2011-2022 走看看