传送门

知识点:卡特兰数/动态规划

法一:动态规划

由题意易知字符串的任何一个前缀都满足\(cnt(A) - cnt(B) \le n , cnt(B)-cnt(A)\le m\)

\(d[i][j]\) 表示前\(i\) 个字符,有 \(j\) 个\(A\) ,有\(i-j\) 个\(B\) 的方案数

  • \(d[0][0] = 1,d[2*n+2*m][n+m] 为答案\)
  • 当\(j-(i-j)\le n,(i-j)-j\le m\) 时,\(d[i][j] = d[i-1][j] + d[i-1][j-1]\)
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
typedef long long ll;
int n,m;
ll d[4010][2010];
int main(){
while(~scanf("%d%d",&n,&m)){
d[0][0] = 1;
for(int i=1;i<=2*(n+m);i++){
for(int j=0;j<=i && j <= (n+m);j++){
int a = j;
int b = i - j;
if(a - b > n || b - a > m)continue;
d[i][j] = (d[i-1][j] + d[i-1][j-1])%mod;
}
}
printf("%lld\n",d[2*(n+m)][(n+m)]);
for(int i=1;i<=2*(n+m);i++){
for(int j=0;j<=i && j <=(n+m);j++)
d[i][j] = 0;
}
}
return 0;
}

法二:组合数学

设\(x\) 为A的个数,\(y\)为B的个数,那么由\((0,0)\rightarrow (n+m,n+m)\)的路径上面必须满足\(x-y\le n,y-x\le m\) 两个条件。

在经典的卡特兰数路径计数问题中就有提到,详情请参考:https://oi-wiki.org/math/catalan/

将上面两个限制放在图中就是两个直线,然后求起点到终点的非降路径方案数(非降的意思是x和y不能变小),先考虑偏上的那条线(下面同理可得),如果我们有一条路径越过了\(y=x+m\) 这条线,那么该路径上面一定会有一个点在\(y=x+m+1\)这条线上。

从上图中不难看出来,这样的路径等效于从\((-m-1,m+1)\)到\((n+m,n+m)\) 的路径,因为\((0,0)与(-m-1,m+1)关于y=x+m+1 对称\)。

  1. \((0,0)\rightarrow (n+m,n+m)\) 的所有非降路径数为\(C_{2n+2m}^{n+m}\)
  2. \((-m-1,m+1)\rightarrow (n+m,n+m) 的所有非降路径数为\)C_{2n+2m}^{n-1}$
  3. \((n+1,-n-1)\rightarrow (n+m,n+m)\) 的所有非降路径数位\(C_{2n+2m}^{m-1}\)

所以总答案为\(C_{2n+2m}^{n+m}-C_{2n+2m}^{n-1}-C_{2n+2m}^{m-1}\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 10010;
const int p = 1e9+7;
ll jc[N],inv[N];
int n,m;
ll ksm(ll a,ll b){
ll res = 1;
for(;b;b >>= 1){
if(b & 1)res = res * a % p;
a = a * a % p;
}
return res;
}
ll C(int a,int b){
return jc[a] * inv[b] % p * inv[a-b] % p;
}
int main(){
jc[0] = inv[0] = 1;
for(int i=1;i<=4000;i++)jc[i] = jc[i-1] * i % p,inv[i] = ksm(jc[i],p-2);
while(~scanf("%d%d",&n,&m)){
int s = 2*(n+m);
printf("%lld\n",(C(s,s/2) - (C(s,n-1) + C(s,m-1))%p + p) % p);
}
return 0;
}

2019牛客暑期多校训练营(第一场)E ABBA (DP/卡特兰数)的更多相关文章

  1. 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)

    题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...

  2. 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem

    题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3  4 2 3 4 输出:0 0 1 题解: 认真想一 ...

  3. 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)

    layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...

  4. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

  5. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  6. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  7. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  8. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  9. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  10. 2019牛客暑期多校训练营(第八场)E.Explorer

    链接:https://ac.nowcoder.com/acm/contest/888/E来源:牛客网 Gromah and LZR have entered the fifth level. Unli ...

随机推荐

  1. Command3

    压缩和解压 gzip gunzip .gz 指定文件必须带后缀 gzip file filename.gz zip unzip .zip unzip filename.zip directory zi ...

  2. 转载-Oracle 数据库导入导出 dmp文件

    首先询问对方数据库的表空间名称和大小,然后在你的oracle中建立相应表空间,最后使用命令导入.导出数据.补充:1.要新建一个数据库: Oracle数据导入导出imp/exp就相当于oracle数据还 ...

  3. Mac使用HomeBrew

    前言 考虑许久终于决定入手mac耍耍,还是因为要找工作了,手上的win本大学入的,现在使用卡顿太多,另外就是mac作为程序员之友仰慕已久.决定在PDD入了.到手后发现mac真的跟win有很大差别.还是 ...

  4. 【Sphinx】 为Python自动生成文档

    sphinx 前言 Sphinx是一个可以用于Python的自动文档生成工具,可以自动的把docstring转换为文档,并支持多种输出格式包括html,latex,pdf等 开始 建一个存放文档的do ...

  5. 创建mysql帐户

    CREATE USER 'username'@'host' IDENTIFIED BY 'password';

  6. oracle move表空间(分区表,索引)

    1.修改分区表分区表空间 SELECT 'ALTER TABLE ' || table_owner || '.' || TABLE_NAME || ' MOVE PARTITION ' || PART ...

  7. 代码页(CodePage)列表

    代码页编号    国家地区或语言37                 IBM037    IBM EBCDIC (US-Canada)    437                 IBM437    ...

  8. Android事件分发机制三:事件分发工作流程

    前言 很高兴遇见你~ 本文是事件分发系列的第三篇. 在前两篇文章中,Android事件分发机制一:事件是如何到达activity的? 分析了事件分发的真正起点:viewRootImpl,Activit ...

  9. vue中computed/method/watch的区别

    摘要:本文通过官方文档结合源码来分析computed/method/watch的区别. Tips:本文分析的源码版本是v2.6.11,文章中牵涉到vue响应式系统原理部分,如果不是很了解,建议先阅读上 ...

  10. CMU数据库(15-445)-实验2-B+树索引实现(中)删除

    3. Delete 实现 附上实验2的第一部分 https://www.cnblogs.com/JayL-zxl/p/14324297.html 3. 1 删除算法原理 如果叶子结点中没有相应的key ...