ABC 312D題 Count Bracket Sequences

Linear_L發表於2024-06-01

題意

  • 給定一個非空的字串,其由(,),?三個字元構成,其中?可以被(或者)給替換掉,求替換後的字串是符合括號匹配的情況下的方案數。最後答案對mod=998244353取模

思路

  1. 應該算是一個板題,一開始的想法是往卡特蘭數的方向思考,但是可能是我太水了沒想出來,然後一想到卡特蘭數的dp求法,就順理成章的想到了dp。
  2. 我們將(替換成1,)替換成-1,對於一個合法的括號匹配來說,對於任何一項i,我們都有字首和為正數,否則就不合法了。我們定義dp[i][j]為到達字串的第i位,字首和為j的情況下的方案數,那麼我們就可以很容易得出狀態轉移方程:
  • dp[i][j]=dp[i-1][j-1],(a[i]==1)
  • dp[i][j]=dp[i-1][j+1]+dp[i-1][j-1],(a[i]==0)
  • dp[i][j]=dp[i-1][j+1],(a[i]==-1)
  1. 注意一下字串的開頭,當j==0時,防止陣列越界,我們單獨處理一下。當然注意取模,先取模後相加。

程式碼

string s;
cin>>s;
int n=s.length();
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
	if(s[i-1]=='(') a[i]=1;
	else if(s[i-1]==')') a[i]=-1;
	else a[i]=0;
}
for(int i=1;i<=n;i++)
{
	for(int j=0;j<=i;j++)
	{
		if(a[i]==1) dp[i][j]=dp[i-1][j-1]%mod;
		else if(a[i]==0)
		{
		    if(i==1&&j==0) dp[i][j]=0;
		    else dp[i][j]=(dp[i-1][j+1]%mod+dp[i-1][j-1]%mod)%mod;
		}
		else dp[i][j]=dp[i-1][j+1]%mod;
	}
}
cout<<dp[n][0]%mod<<endl;
return 0;

}

相關文章