链接: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;
}