社区讨论

求调,有代码大意

P7914[CSP-S 2021] 括号序列参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mhj4xwm0
此快照首次捕获于
2025/11/03 20:47
4 个月前
此快照最后确认于
2025/11/03 20:47
4 个月前
查看原帖
动态规划,数组意义
f:l到r之间且lr匹配的方案数
g:l到r之间且lr不匹配的方案数
che:l到r能不能形成全*区间
h:l到r形如SA的区间方案数量
大致思路(最重点的)
为了避免重复,令形如ASB的区间A一定是左右匹配了的
CPP
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
ll read(){
	register ll x=  0, f = 1;
	register char c;
	for(c =  getchar(); !isdigit(c); c = getchar())if(c == '-')f = -1;
	for(;isdigit(c); c = getchar())x = (x << 1) + (x << 3) + c - '0';
	return x * f;
}
const int MAXN = 500 + 5;
const ll MOD = 1000000000 + 7;
ll n, K, f[MAXN][MAXN], g[MAXN][MAXN], h[MAXN][MAXN], che[MAXN][MAXN];
char c[MAXN];
inline bool check(ll u, char tar){
	 return (c[u] == tar || c[u] == '?');
}
signed main(){
	freopen("bracket3.in", "r", stdin);
	freopen("bracket.out", "w", stdout);
	cin >> n >> K;
	cin >> c + 1;
	for(int i = 1; i <= n; i++)
		for(int j = i; j <= min(n, i + K - 1); j++){
			if(!check(j, '*'))break;
			che[i][j] = 1;
		}
	for(ll len = 2; len <= n; len++){
		for(ll l = 1; l + len - 1 <= n; l++){
			ll r = l + len - 1;
			if(check(l, '(') && check(r, ')')){
				f[l][r] = f[l + 1][r - 1] + g[l + 1][r - 1];//(A)
				f[l][r] = (f[l][r] + che[l + 1][r - 1]) % MOD;//(S)

				for(ll k = l + 1; k < r - 1; k++)f[l][r] = (f[l][r] + (f[l + 1][k] + g[l + 1][k]) * che[k + 1][r - 1]) % MOD;//(AS)
				for(ll k = l + 1; k < r - 1; k++)f[l][r] = (f[l][r] + che[l + 1][k] * (f[k + 1][r - 1] + g[k + 1][r - 1])) % MOD;//(SA)

				for(ll k = l + 1; k < r; k++)g[l][r] = (g[l][r] + f[l][k] * (g[k + 1][r] + f[k + 1][r])) % MOD;//AB
				for(ll k = l + 1; k < r; k++)g[l][r] = (g[l][r] + f[l][k] * h[k + 1][r]) % MOD;//ASB
			}
			if(check(r, ')'))for(ll k = l; k < r; k++)h[l][r] = (h[l][r] + che[l][k] * (f[k + 1][r] + g[k + 1][r])) % MOD;
			
		}
	}
	cout << (f[1][n] + g[1][n]) % MOD << endl;
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...