Codeforces Round #554 (Div. 2) D Neko and Aki's Prank(记忆化DFS)

博客围绕Neko和Aki的故事展开,引出关于所有长度为2n的正确括号序列构成的字典树最大匹配问题。介绍了正确括号序列的定义,给出输入输出要求及示例,还提及贪心和记忆化DFS思想。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D. Neko and Aki's Prank

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Neko is playing with his toys on the backyard of Aki's house. Aki decided to play a prank on him, by secretly putting catnip into Neko's toys. Unfortunately, he went overboard and put an entire bag of catnip into the toys...

It took Neko an entire day to turn back to normal. Neko reported to Aki that he saw a lot of weird things, including a trie of all correct bracket sequences of length 2n2n.

The definition of correct bracket sequence is as follows:

  • The empty sequence is a correct bracket sequence,
  • If ss is a correct bracket sequence, then (s)(s) is a correct bracket sequence,
  • If ss and tt are a correct bracket sequence, then stst is also a correct bracket sequence.

For example, the strings "(())", "()()" form a correct bracket sequence, while ")(" and "((" not.

Aki then came up with an interesting problem: What is the size of the maximum matching (the largest set of edges such that there are no two edges with a common vertex) in this trie? Since the answer can be quite large, print it modulo 109+7109+7.

Input

The only line contains a single integer nn (1≤n≤10001≤n≤1000).

Output

Print exactly one integer — the size of the maximum matching in the trie. Since the answer can be quite large, print it modulo 109+7109+7.

Examples

Input

Copy

1

Output

Copy

1

Input

Copy

2

Output

Copy

3

Input

Copy

3

Output

Copy

9

Note

The pictures below illustrate tries in the first two examples (for clarity, the round brackets are replaced with angle brackets). The maximum matching is highlighted with blue.

 

贪心    记忆化DFS  思想很重要

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1005;
ll mod=1e9+7;
ll n;
ll dp[maxn][maxn][2];
ll dfs(ll l,ll r,ll flag)
{
    if(dp[l][r][flag])
        return dp[l][r][flag];
    ll ans=0;
    ll p=flag;
    if(l<n)
    {
        if(flag==0)
        {
            ans=ans+dfs(l+1,r,1)+1;
            ans%=mod;
            flag=1;
        }
        else
        {
            ans=ans+dfs(l+1,r,0);
        }

    }
    if(r<l)
    {
        if(flag==0)
        {
            ans=ans+dfs(l,r+1,1)+1;
            ans%=mod;
            flag=1;
        }
        else
        {
            ans=ans+dfs(l,r+1,0);
        }
    }
    dp[l][r][p]=ans;
    return ans;
}
int main()
{
    memset(dp,0,sizeof(dp));
    cin>>n;
    cout<<dfs(0,0,0);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值