【2019 Niuke Summer School First Session】E Question ABBA

Topic link

General meaning

Yes (n + m) (n + m)(n+m ) letters A and(n + m) (n + m)(n+m ) letters B, forming a length of2 ∗ (n + m) 2*(n + m)2(n+m ) string, and make the string havennn "AB" andmmm "BA", find the number of possible combinations (mod 1e9+7)
For example, when n = 1 m = 2, there can be such strings (not all strings):
ABBABA
ABBBAA
BBABAA The
above three characters Strings meet the conditions

Problem solving ideas

Consider recursion, assuming that there is already a string that satisfies certain "prerequisites" (this should be understood as mathematical induction, and if n-1 is satisfied),
consider the followingAdd a character to the end of the stringCase. Only two possibilities: A plus or plus B ( which is not white to say it )
but consider the extreme case, we can get some simple and obvious condition (N A represents the number of A is already in the string, N B Similarly)
If the composition of the string is similar to this:

AAAAABBBBBBBB

In this string, only AB can be combined, but BA cannot be combined.
At this time, we assume nnn is 5
and this character can only and must be combined into 5 AB, that is to say, we can add characters next, we can only add A but not B.
At this time, we push forward. If such a string appears, Before, the following state must appear:

AAAAA

That is, in the case of 5 A, we can get a definite relation:

NB = 0 and NA <= n

Generalizing to the case of B, the optimal situation is that all Bs are used to form BA , then we can get the relationship we really need:

NA - NB <= n

In the same way, compared to B, we can get

NB - NA <= m

Combine the above two formulas

-n < NA - NB <= m

Therefore, the DP array is established according to the subscript N A -N B , the subscript range is -n to m (both inclusive). The content of the DP is the number of plans (mod 1e9 + 7), and the recurrence formula is
dp [i] = dp [ i − 1] + dp [i + 1] dp[i] = dp[i-1] + dp [i + 1]dp[i]=dp[i1]+dp[i+1 ]
Among them, dp[i-1] refers to adding a B (adding a B makes NA-NBsmaller). And dp[i + 1] refers to adding an A.
When considering whether it is a forward dp or a reverse dp, both values ​​have priority over dp[i] to update first (dp[i-1] and dp[i + 1] will Newer than dp[i]), so two dp arrays are used, with the initial value dp[0]=1. After every two dp, the value of dp[0] is the answer.

AC code

#include <bits/stdc++.h>
 
using namespace std;
 
#define MAXN 2100
#define MOD (int)(1e9 + 7)
typedef long long ll;

ll dp[MAXN][2];
 
int trans(int x) {
    
    
    return x + 1000;
}
 
int main()
{
    
    
#ifdef ACM_LOCAL
    freopen("debug.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);
    int n, m;
    while (cin >> n >> m) {
    
    
        memset(dp, 0, sizeof(dp));
        dp[n][1] = 1;
        int cur = 0;
        int last = 1;
        for (int i = 0; i < 2 * (n + m); i++) {
    
    
            for (int j = -n; j <= m; j++) {
    
    
                if (j != -n) {
    
    
                    dp[j + n][cur] += dp[j - 1 + n][last];
                    dp[j + n][cur] %= MOD;
                }
                if (j != m) {
    
    
                    dp[j + n][cur] += dp[j + 1 + n][last];
                    dp[j + n][cur] %= MOD;
                }
            }
            for (int j = -n; j <= m; j++) {
    
    
                dp[j + n][last] = 0;
            }
            swap(cur, last);
        }
        cout << dp[n][last] << endl;
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/m0_43448982/article/details/96778336