The meaning of problems: ask you a length of 2 * (n + m) by a string of (n + m) th A and B, AB required sequence of n and m BA sequence, there are several such strings
https://ac.nowcoder.com/acm/contest/881/E
Ideas:
Suppose there is a valid string, because the sub-sequence of n and m AB BA, then obviously there will be for the first n A of AB A, B must first m of the BA B. Because if I was the first n A there is a BA of A, I was not able to easily find a more back from A to B with this, then obviously the first n A must for the AB of A.
We assume DP [i] [j] for the i-th Aj B, let A:
If i <n that it can be placed directly A, above reason
If i> = n, then we need to ensure that when A and B give BA with the front, then the current needed BA A is min (j, m) number, he has given the i - n a, so that (i - n ) <min (j, m) can then continue to discharge.
Code:
#include<cmath> #include<set> #include<map> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 2e3 + 5; const int M = 50 + 5; const ull seed = 131; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; ll dp[maxn][maxn]; int main(){ int n, m; while(~scanf("%d%d", &n, &m)){ for(int i = 0; i <= n + m; i++){ for(int j = 0; j <= n + m; j++){ dp[i][j] = 0; } } dp[0][0] = 1; for(int i = 0; i <= n + m; i++){ for(int j = 0; j <= n + m; j++){ if(i < n || (i - n) < j){ //push A dp[i + 1][j] = (dp[i + 1][j] + dp[i][j]) % MOD; } if(j < m || (j - m) < i){ //push B dp[i][j + 1] = (dp[i][j + 1] + dp[i][j]) % MOD; } } } printf("%lld\n", dp[n + m][n + m]); } return 0; }