基于卡塔兰数的括号匹配

这是暑假个人赛第一场的一个困扰了我一个下午的题!

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;
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值