HihoCoder 1568 不一定合法括号序列

题目链接


描述
我们定义长度为2n的不一定合法括号序列为左右括号个数均为n的序列。

我们定义不一定合法括号序列的bad指数为这个序列当中没有对应右括号的左括号的个数。

给出n,k。求bad指数为k的长度为2n的不一定合法括号序列的个数。

由于答案很大,你只需要输出对109 + 7取余的结果。

输入
一行两个整数n,k

对于30%的数据 1 ≤ k ≤ n ≤ 10

对于100%的数据 1 ≤ k ≤ n ≤ 300

输出
一个整数表示答案。

样例输入
2 1
样例输出
3

思路:

动态规划方法,三元组(i,j,k)刻画状态,三元组表示考虑到第i个位置,已经出现了左括号j个,未匹配的左括号k个。
转移方程:

左括号 ( 坏数+1

dp(i+1,j+1,k+1) = dp(i+1,j+1,k+1) + dp(i,j,k)

右括号 ( 坏数-1

dp(i+1,j,k-1) = dp(i+1,j,k-1) + dp(i,j,k)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
const int N = 305;
const int mod = 1e9 + 7;
int dp[N*2][N][N];
int n,k;
int main()
{
    scanf("%d%d", &n, &k);
    int m = 2*n;
    dp[0][0][0] = 1;
    for(int i = 1; i <= m; i++)
    {
        for(int j = 0; j <= min(n,i); j++)
        {
            for(int s = 0; s <= j; s++)
            {

                dp[i+1][j+1][s+1]  += dp[i][j][s];
                dp[i+1][j][max(0,s-1)] += dp[i][j][s];
                dp[i+1][j+1][s+1] %= mod;
                dp[i+1][j][max(0,s-1)] %= mod;
                /*
                if(s == 0)
                    dp[i][j][0] = dp[i-1][j][0] + dp[i-1][j][1];
                else
                {
                    if(j == 0)
                        dp[i][j][s] = dp[i-1][j][s+1];
                    else
                        dp[i][j][s] = dp[i-1][j-1][s-1] + dp[i-1][j][s+1];
                }
                dp[i][j][s] %= mod;
                */
            }
        }
    }
    printf("%d
", dp[m][n][k]);
    return 0;
}
原文地址:https://www.cnblogs.com/Alruddy/p/7476629.html