题目描述
合法括号序列 键盘上有左括号(,右括号),和退格键-,共三个键。 牛牛希望按键n次,使得输入的字符串恰好一个合法的括号序列。 每按一次左括号(,字符串末尾追加一个左括号( 每按一次右括号),字符串末尾追加一个右括号) 每按一次退格键-,会删掉字符串的最后一个字符, 特别的,如果字符串为空,牛牛也可以按退格,但是什么都不会发生。 输出方案数对p取模,注意p可能不是质数。 注:只要按键方法不同,就是不同的方案,即使得到的序列一样。
输入描述:
输入一行两个整数n, p
输出描述:
输出一行一个整数表示答案。
示例1
输入
2 4
输出
0
说明
答案是4,有以下4个合法的序列()(-)—
备注:
对于所有数据: 2 <= n <= 1000, 2 <= p <= 1000030分: n <= 4070分: n <= 100
#include<bits/stdc++.h>
using namespace std;
inline int rd()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
long long n,mod,dp[2005][2005],c[2005];
int main()
{
c[0]=c[1]=1;
cin>>n>>mod;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
c[i]=(c[i]+c[j-1]*c[i-j])%mod;
}
}
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=i;j++)
{
dp[i][j]=(dp[i-1][max(j-1,0)]+2*dp[i-1][j+1])%mod;
}
}
long long ans=0;
for(int i=0;2*i<=n;i++)
{
ans=(ans+dp[n][i*2]*c[i])%mod;
}
cout<<ans;
return 0;
}
来源:nkw