你有一个长为2∗(n+m)2∗(n+m)的字符串,每个位置填上A或B, 问你有多少个这样的字符串使得最终能提取出nn个"AB"子序列和mm个"BA"子序列
dp即可,dp[i][j]表示前i个位置用了j个A的方案数
通过n,m来计算当前位置最多已经用了多少个A。
额,裸dp模就好了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
const int N=1e5+5;
const int mod=1e9+7;
int dp[12005][6000];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
if(n != 0)dp[1][1] = 1;
if(m != 0)dp[1][0] = 1;
for(int i=1;i<=(n+m)*2;i++)
{
for(int j=0;j<=i;j++)
{
if(i-j*2>n||2*j-i>m)
{
dp[i][j]=0;
continue;
}
if(j==0)dp[i][j]=1;
dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%mod;
}
}
cout<<dp[(n+m)*2][n+m]<<endl;
}
return 0;
}
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
using namespace std;
const int madulo = 1e9 + 7;
long long n, m;
long long dp[2005][2005];
long long dfs(long long a, long long b) {
if(dp[a][b] != 0) return dp[a][b];
if(a < b + n && a < n + m) {
dp[a][b] = (dp[a][b] + dfs(a+1, b)) % madulo;
}
if(b < a + m && b < n + m) {
dp[a][b] = (dp[a][b] + dfs(a, b+1)) % madulo;
}
return dp[a][b] % madulo;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while(cin >> n >> m) {
for(int i=0; i<=n+m; i++)
for(int j=0; j<=n+m; j++)
dp[i][j]=0;
dp[n+m][n+m] = 1;
cout << dfs(0, 0) << endl;
}
return 0;
}