这是暑假个人赛第一场的一个困扰了我一个下午的题!
Brackets
This year MK is 5 years old. So he decides to learn some arithmetic. But he was confused by how to write the brackets. He has already known that the brackets should match when writing them correctly. Such as “()(())” is correct but “())(” is not.
The problem is that, if there are N pairs of brackets, how many ways that MK can write them correctly?
Input
There are several test cases. Each case contains a number N (1 <= N <= 1000) indicating the pairs of brackets.
Output
For each case, please output the answer mod 1,000,000,007.
Sample Input :
5
7
Sample Output :
42
429
-----------------------------------------------------------------------------------------------------------------------------------------
开始做这个题的时候用的公式是是f(n)=f(n-1)*f(4*n-2)/n+1
但是后面测试的时候发现在对f(n)取模的时候会出错。
然后听学长的用了这个公式f(n)=f(0)*f(n-1)+f(1)*f(n-2).........f(n-1)*f(0) (n>=2)
而这个题目的原理是,对正确的括号进行匹配。
我们可以假定(只对最近的)进行匹配
比如:
()()()()() 第一种(只对最近的)匹配所以总共就有f(1)*f(n-1)种情况
(()()()) 第二种就是最左边有两个((所以就有f(2)*f(n-2)种情况
以此类推
但是由于是在输入了n之后进行求解。所以在第一次输入之后,第二次输入时又会进行一次运算,然后输入相同的数时输出就会改变。我觉得应该是数组初始化的问题。
这是最初的代码:
#include <stdio.h>
#include <iostream>
using namespace std;
#define M 1000000007
__int64 a[1010];
int main()
{
int n,i,j;
while(~scanf("%d",&n))
{
a[0]=1;
for(i=1;i<=1000;i++)
for(j=0;j<i;j++)
{
a[i]+=a[j]*a[i-j-1]%M;
a[i]%=M;
}
printf("%I64d\n",a[n]);
}
return 0;
}
----------------------------------------------------------------------------------------------------------------------------------------------------------
然后的话,就把计算提到了输入前面。先对范围内的进行一次运算,再输入n进行求解输出,然后果断测试没问题了啊!
怎么说呢,还是自己的思维问题吧。以后还是要多想一些其他的方法!
修改之后的代码:
#include <stdio.h>
#include <iostream>
using namespace std;
#define M 1000000007
__int64 a[1010];
int main()
{
int n,i,j;
a[0]=1;
for(i=1;i<=1000;i++)
for(j=0;j<i;j++)
{
a[i]+=a[j]*a[i-j-1]%M;
a[i]%=M;
}
while(~scanf("%d",&n))
{
printf("%I64d\n",a[n]);
}
return 0;
}