列表

详情


NC18413. 括号

描述

小A有一个只包含左右括号的字符串S。但他觉得这个字符串不够美观,因为它不是一个合法的括号串。一个合法的括号串是这样定义的:
1. ()是合法的括号串
2. 若A是合法的括号串,则(A)则是合法的括号串
3. 若A,B是合法的括号串,则AB也是合法的括号串。

小A现在希望删掉S中若干个字符,使得剩下的字符串是一个合法的括号串。小A想知道有多少不同的方案。两个方案是不同的,当且仅当他们删除的位置不同。比如当S是(()时,有两种方案。分别是删掉第一个位置,或是删掉第二个位置。

输入描述

第一行一个整数n,代表S的长度。
第二行输入n个字符,字符要么是(,要么是)。代表串S。

输出描述

一行一个整数,代表不同的方案数。答案对10^9+7取模。

示例1

输入:

8
)(()(())

输出:

30

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Pascal(fpc 3.0.2) 解法, 执行用时: 743ms, 内存消耗: 484K, 提交时间: 2018-09-09 07:52:35

var n,i,j:longint;
s:ansistring;
a:array[-1..10000] of longint;
begin
readln(n);
readln(s);
a[0]:=1;
for i:=1 to n do
  if s[i]='(' then
    for j:=n-i-1 downto 0 do
      a[j+1]:=(a[j+1]+a[j]) mod 1000000007
  else
    for j:=1 to n-i+1 do
      a[j-1]:=(a[j-1]+a[j]) mod 1000000007;
        write((a[0]-1)mod 1000000007)
end.

C++14(g++5.4) 解法, 执行用时: 126ms, 内存消耗: 492K, 提交时间: 2020-04-26 20:37:22

#include<iostream>
using namespace std;
int f[10005]={1},x;
int main(){
    int n,m=1e9+7;string s;
    cin>>n>>s;
    for(int i=0;i<n;i++) x+=(s[i]=='(');
    for(int i=1;i<=n;i++)
    if(s[i-1]=='(') for(int j=x-1;j>=0;j--) f[j+1]=(f[j+1]+f[j])%m;
    else for(int j=1;j<=x;j++) f[j-1]=(f[j-1]+f[j])%m;
    cout<<f[0]-1;
}

C++11(clang++ 3.9) 解法, 执行用时: 75ms, 内存消耗: 584K, 提交时间: 2018-09-08 22:52:43

#include <iostream>
using namespace std;
int f[10005]={1},x;
int main()
{
int n,m=1e9+7;string s;
cin>>n>>s;
for(int i=0;i<n;i++) x+=(s[i]=='(');
for(int i=1;i<=n;i++)
if(s[i-1]=='(')for(int j=x-1;j>=0;j--) f[j+1]=(f[j+1]+f[j])%m;
else for(int j=1;j<=x;j++) f[j-1]=(f[j-1]+f[j])%m;
cout<<f[0]-1;
}

上一题