1075. 括号匹配 11.07
Description
括号匹配发布了11.07版XD
给定一个N表示字符串的长度,问此长度的由左右小括号和小写字母a构成的合法的字符串有多少个
合法的字符串如下定义:
1 空串是合法的
2 如果P是合法的,那么aP也是合法的
3 如果P是合法的,那么(P)也是合法的
4 如果P和Q都是合法的,那么PQ也是合法的
请输出答案除以19301的余数
Input Format
N.(0<N≤3333)
Output Format
答案除以19301的余数
Sample Input 1
1
Sample Output 1
1
Sample Input 2
3
Sample Output 2
4
Sample Input 3
4
Sample Output 3
9
虽然能一眼看出用动归,但是比较难的就是找到状态转移方程,因为需要避免重复。
对第一个位置分类,若为a,则有f(n-1)种,若为(,则遍历对应的右括号的位置,假设为i,则有(i-1)*(n-i-1)种,这样状态转移方程就写好了。
代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 //括号匹配 2 #include <iostream> 3 #include <cstring> 4 using namespace std; 5 6 int main(){ 7 int n,i,j; 8 9 cin>>n; 10 int num[n+10]; 11 memset(num,0,sizeof(num)); 12 num[0] = 1; 13 num[1] = 1; 14 for (int i = 2;i <= n;++i){ 15 num[i] += num[i-1]; 16 for (int j = 1;j < i;++j){ 17 num[i] += num[j-1]*num[i-j-1]; 18 num[i] %= 19301; 19 } 20 21 } 22 // for (int i = 0;i <= n;++i) cout<<num[i]<<' ';cout<<endl; 23 cout<<num[n]; 24 25 return 0; 26 }