zoukankan      html  css  js  c++  java
  • [dp] Jzoj P5804 简单的序列

    Description

    从前有个括号序列 s,满足 |s| = m。你需要统计括号序列对 (p, q) 的数量。
    其中 (p, q) 满足 |p| + |s| + |q| = n,且 p + s + q 是一个合法的括号序列。
     

    Input

    从文件 bracket.in 中读入数据。第一行两个正整数 n, m。
    第二行一个长度为 m 的括号序列,表示 s。
     

    Output

    输出到文件 bracket.out 中。
    输出一行一个整数,表示符合条件的 (p, q) 的数量对 10^9 + 7 取模的值。
     
     
     

    Sample Input

    【样例 1 输入】
    4 1 (
    【样例 2 输入】
    4 4 (())
    【样例 3 输入
    4 3 (((
     

    Sample Output

    【样例 1 输出】
    4
    【样例 2 输出】
    1
    【样例 3 输出】
    0
     
     

    Data Constraint

    对于 10% 的数据,n ≤ 20;
    对于 25% 的数据,n ≤ 200;
    对于另外 5% 的数据,n = m;
    对于 55% 的数据,n − m ≤ 200;
    对于 100% 的数据,1 ≤ m ≤ n ≤ 10^5, n − m ≤ 2000。

    题解

    • 我们可以把左括号看成+1,右括号看成-1
    • 那么一个合法的括号序列就是左括号>=右括号
    • 设f[i][j]为长度为i的序列 左括号比右括号多j个 的方案数
    • 状态转移方程明显就是:f[i-1][j-1]+f[i-1][j+1]
    • 那么考虑如何求最终的方案数
    • 首先要满足左括号多于右括号,和 |p| + |s| + |q| = n
    • 每次枚举一个i表示前面的p序列的长度,再枚举一个j表示p序列左括号比右括号多的个数
    • 那么就是f[i][j]*f[n-m-i][j+tot](tot为原来序列中左括号比右括号多的个数)

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 using namespace std;
     6 const long long mo=1e9+7;
     7 int n,m,tot,ltot;
     8 char s[100010];
     9 long long ans,f[2010][2010];
    10 int main()
    11 {
    12     freopen("bracket.in","r",stdin);
    13     freopen("bracket.out","w",stdout);
    14     scanf("%d%d",&n,&m);
    15     scanf("%s",s);
    16     for (int i=0;i<m;i++)
    17     {
    18         if (s[i]=='(') tot++; else tot--;
    19         if (i==0) ltot=tot; else ltot=min(tot,ltot);
    20     }
    21     f[0][0]=1;
    22     for (int i=1;i<=n-m;i++)
    23         for (int j=0;j<=i;j++)
    24             if (j==0) f[i][j]=f[i-1][j+1];
    25             else f[i][j]=(f[i-1][j-1]+f[i-1][j+1])%mo;
    26     for (int i=0;i<=n-m;i++)
    27         for (int j=0;j<=i;j++)
    28             if (j+tot<=n-m&&j+ltot>=0)
    29                 (ans+=f[i][j]*f[n-m-i][j+tot])%=mo;
    30     printf("%lld",ans);
    31     return 0;
    32 }
  • 相关阅读:
    excel成绩统计公式
    freebsd Cacti
    图片处理程序
    php 图片水印+文字水印函数,但是不能设置透明
    PHP计算两个时间之差的函数(年,月,周,日,小时,分钟,秒数)
    php图片水印(可以设置透明度)
    使用函数递归实现基于PHP和MySQL的动态树型菜单[转]
    PHP实现MYSQL备份
    FreeBSD备忘录转载
    超级简单但超级实用的 PHP 的 mysql 类
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9464185.html
Copyright © 2011-2022 走看看