链接:https://ac.nowcoder.com/acm/contest/881/E

来源:牛客网

ABBA

时间限制:C/C++ 2秒,其他语言4秒

空间限制:C/C++ 524288K,其他语言1048576K

64bit IO Format: %lld

题目描述

Bobo has a string of length 2(n + m) which consists of characters A and B. The string also has a fascinating property: it can be decomposed into (n + m) subsequences of length 2, and among the (n + m) subsequences n of them are AB while other m of them are BA.

Given n and m, find the number of possible strings modulo

(

10

9

+

7

)

(109+7).

输入描述:

The input consists of several test cases and is terminated by end-of-file.

Each test case contains two integers n and m.

0



n

,

m



10

3

0≤n,m≤103

  • There are at most 2019 test cases, and at most 20 of them has

    max

    {

    n

    ,

    m

    }

50

max{n,m}>50.

输出描述:

For each test case, print an integer which denotes the result.

示例1

输入

复制

1 2

1000 1000

0 0

输出

复制

13

436240410

1

题意:

问给你长度为2*(n+m)的字符串,由n+m个‘A'和’B'组成,要求有n个AB子序列,和m个BA子序列,这样的串有多少种 ?

思路:

先看一个合法串什么什么样的,因为子序列有n个AB,m个BA,那么显然前n个A必为AB的A,前m个B必为BA的B,因为如果我前n个A中有一个是BA的A,那么我们可以从更后面 随便找一个A给这个B用。

定义dp状态: dp[i][j] 为放了i个A,j个B,合法的状态数。

来看转移:

放A:

如果i < n 那么可以直接放这个A,理由如上。

如果i>=n 那么我们要确保 这个放的A能给前面的B当作BA中的A用,那么当前我们BA需要的A是min(j,m) 个

已经给了i-n个,故如果(i-n)<min(j,m) 还可以继续放A

B 同理:

如果j< m 直接放这个B

如果j > = m ,那么我们要确保 放这个B能给前面的一个A当作AB中的B用,那么我们AB需要的B是 min(i,n )个

已经放了 j-m 个,如果(j-m) <min(i,n) 就可以继续放这个B

细节见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
ll dp[3000][2005];
const ll mod = 1e9 + 7;
int n, m;
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
gbtb;
while (cin >> n >> m) {
repd(i, 0, n + m) {
repd(j, 0, n + m) {
dp[i][j] = 0;
}
}
dp[0][0] = 1;
repd(i, 0, n + m) {
repd(j, 0, m + n) {
if (i < n || i - n < j) {
dp[i + 1][j] += dp[i][j];
dp[i + 1][j] %= mod;
}
if (j < m || (j - m) < i) {
dp[i][j + 1] += dp[i][j];
dp[i][j + 1] %= mod; }
}
}
cout<<dp[n+m][n+m]<<endl;
}
return 0;
} inline void getInt(int *p)
{
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
} else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}

2019牛客多校第一场E ABBA(DP)题解的更多相关文章

  1. 2019牛客多校第一场E ABBA dp

    ABBA dp 题意 给出2(N+M)个AB字符,问能构造出N个AB子序列和M个BA子序列组成的2*(n+m)的序列种类有多少 思路 碰到计数构造类的题目,首先要去找到判断合法性的条件,即什么情况下合 ...

  2. 2019牛客多校第一场 E-ABBA(dp)

    ABBA 题目传送门 解题思路 用dp[i][j]来表示前i+j个字符中,有i个A和j个B的合法情况个数.我们可以让前n个A作为AB的A,因为如果我们用后面的A作为AB的A,我们一定也可以让前面的A对 ...

  3. 2019牛客多校第一场E ABBA 贪心 + DP

    题意:问有多少个有(n + m)个A和(n + m)个B的字符串可以凑出n个AB和m个BA. 思路:首先贪心的发现,如果从前往后扫,遇到了一个A,优先把它看成AB的A,B同理.这个贪心策略用邻项交换很 ...

  4. 2019 牛客多校第一场 E ABBA

    题目链接:https://ac.nowcoder.com/acm/contest/881/E 题目大意 问有多少个由 (n + m) 个 ‘A’ 和 (n + m) 个 ‘B’,组成的字符串能被分割成 ...

  5. 2019牛客多校第一场 I Points Division(动态规划+线段树)

    2019牛客多校第一场 I Points Division(动态规划+线段树) 传送门:https://ac.nowcoder.com/acm/contest/881/I 题意: 给你n个点,每个点有 ...

  6. 2019牛客多校第一场A-Equivalent Prefixes

    Equivalent Prefixes 传送门 解题思路 先用单调栈求出两个序列中每一个数左边第一个小于自己的数的下标, 存入a[], b[].然后按照1~n的顺序循环,比较 a[i]和b[i]是否相 ...

  7. 2019牛客多校第一场 A.Equivalent Prefixes

    题目描述 Two arrays u and v each with m distinct elements are called equivalent if and only if RMQ(u,l,r ...

  8. 2019 牛客多校第一场 D Parity of Tuples

    题目链接:https://ac.nowcoder.com/acm/contest/881/D 看此博客之前请先参阅吕凯飞的论文<集合幂级数的性质与应用及其快速算法>,论文中很多符号会被本文 ...

  9. 【2019牛客多校第一场】XOR

    题意: 给你一个集合A,里边有n个正整数,对于所有A的.满足集合内元素异或和为0的子集S,问你∑|S| n<=1e5,元素<=1e18 首先可以转化问题,不求∑|S|,而是求每个元素属于子 ...

随机推荐

  1. python - lambda 函数使用

    # if we need it only once and it's quite simple def make_incrementor(n): return lambda x: x + n f = ...

  2. 52N皇后II

    题目:给定一个整数 n,返回 n 皇后不同的解决方案的数量. 来源:https://leetcode-cn.com/problems/n-queens-ii/ 法一: 自己的代码  时间超过百分之90 ...

  3. 封装cookie,自定义过期时间,domain,path

    在使用Cookie进行存储的时候,遇到了许多不可思议的bug,特地标识出来,以作总结. 是这样一个项目,登录是放在官网进行操作的,而登录进入的是后台,后台和官网属于同一域名的不同目录,那么常规进行co ...

  4. C++随笔(1)——关于C++11中的线程创建,join和detach

    主要是和之前的博文有关,之前在这里有一部分代码是通过创建新的进程来应对新的用户请求的,但是基本没怎么解释怎么用的,所以这里做点小笔记. join 首先引入的库: #include <thread ...

  5. 【PyTorch】PyTorch使用LMDB数据库加速文件读取

    PyTorch使用LMDB数据库加速文件读取 原始文档:https://www.yuque.com/lart/ugkv9f/hbnym1 对于数据库的了解较少,文章中大部分的介绍主要来自于各种博客和L ...

  6. 【VS开发】【图像处理】Pleora推出iPORT CL-U3外置抓帧器

    全球领先的高性能视频接口产品供应商Pleora科技公司近日宣布推出可将Camera Link®摄像头转化为USB3Vision™摄像头的首个产品iPORT CL-U3外置抓帧器,树立了另一个行业里程碑 ...

  7. 如何在CBV中使用装饰器

    要区分函数装饰器和方法装饰器得区别 ,方法装饰器得第一个参数是self本身,所以函数装饰器不能用

  8. JavaScript中:地址引用的特性,导致静态初始值被修改

    问题分类 JavaScript,值引用,地址引用 问题描述 开发过程中,服务端将静态配置数据从mysql数据库中读取到内存中,方便调用. 在实现流派功能时,需从数据库中读取流派种类数据到内存中,由于其 ...

  9. 【转帖】是时候给大家介绍 Spring Boot/Cloud 背后豪华的研发团队了。

    是时候给大家介绍 Spring Boot/Cloud 背后豪华的研发团队了. 2019/01/03 http://www.ityouknow.com/springboot/2019/01/03/spr ...

  10. (转)HashMap底层实现原理

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...