牛客 E .ABBA

你有一个长为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;
}
发布了183 篇原创文章 · 获赞 31 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/mlm5678/article/details/96492107