2019牛客暑假多校训练第一场E ABBA dp

链接:https://ac.nowcoder.com/acm/contest/881/E
来源:牛客网

题目描述

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).

输入描述:

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≤1000
* There are at most 2019 test cases, and at most 20 of them has max{n,m}>50

输出描述:

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

输入

1 2
1000 1000
0 0

输出

13
436240410
1

题解

   给定长度为2(n+m)的字符串,要分成n个AB和m个BA.

我们用f[i][j]表示放了i个A,j个B的方案数。然后考虑状态转移。

接着再放一个字符,可以放A,也可以放B。

什么情况能放A呢,我们想想f[i][j]状态下最多能放多少A, 根据贪心策略,我们把现在已经放的j个B都考虑成是BA中的B,因为总共有n个AB,那么n个AB和j个BA最多能放n+j个A。 那么 if(i<n+j)  f[i+1][j]=f[i+1][j]+f[i][j];

什么情况能放B,和A同理,我们把现在已经放的i个A当成AB中的A,那么m个BA和i个AB总共能放m+i个B,那么 

if(j<m+i) f[i][j+1]=f[i][j+1]+f[i][j]

最后f[n+m][n+m]就是答案

这道题要注意f数组初始化不能用memset。因为题目说最多有2019组数据,最多有20组 max(n+m)>50.如果memset会对整个数组初始化,然后就超时了。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=2005;
ll f[maxn][maxn];
int n,m;
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=0;i<=n;i++){
            for(int j=0;j<=m;j++){
                f[i][j]=0;
            }
        }
        f[0][0]=1;
        for(int i=0;i<=n+m;i++){
            for(int j=0;j<=n+m;j++){
                if(i<n+j) f[i+1][j]=(f[i+1][j]+f[i][j])%mod;
                if(j<m+i) f[i][j+1]=(f[i][j+1]+f[i][j])%mod;
            }
        }
        printf("%lld\n",f[n+m][n+m]);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值