2019牛客暑期多校训练营(第一场) E.ABBA 【动态规划】

传送门

题意

有多少个只包含'A''B'的字符串满足:\(n\)个子序列为'AB',\(m\)个子序列为'BA'。

题解

\(f[i][j]\)表示包含\(i\)个'A',\(j\)个'B'且不多于\(n\)个'AB',\(m\)个'BA'的字符串数量。
显然,可以在\(i+j\)位上填'A'或'B',所以\(f[i][j]=f[i-1][j]+f[i][j-1]\)
考虑什么时候可以填'A'或'B'。除去构成'AB'的'A',至少还有\(i-j\)个'A'剩余,那么只有当\(i-j<=n\)的时候,才可以填'A'。同理,只有\(j-i<=m\)的时候,才可以填'B'。这两个条件共同约束,就是正确的转移了。

代码

#include <bits/stdc++.h>
using namespace std;
int n,m;LL f[2*N][2*N];

void solve(){
    for(int i=0;i<=n+m+5;i++) memset(f[i],0,sizeof(LL)*(n+m+5));
    f[0][0]=1;
    for(int i=0;i<=n+m;i++)
        for(int j=0;j<=n+m;j++){
            if(i>0&&i-j<=n) f[i][j]=(f[i][j]+f[i-1][j])%mod;
            if(j>0&&j-i<=m) f[i][j]=(f[i][j]+f[i][j-1])%mod;
        }
    printf("%lld\n",f[n+m][n+m]);
}

int main(){
    while(~scanf("%d%d",&n,&m)) solve();
    return 0;
}
posted @ 2020-06-01 09:15  BakaCirno  阅读(117)  评论(0编辑  收藏  举报