2019 cattle off more school first

2019 cattle off more school first

E: ABBA (greedy + DP)

  • Meaning of the questions: is there \ (n \) a "AB", \ (m \) a "BA", and asked how many can be combined into a sequence. This requirement is the same order of AB and BA, i.e., the relative positions of A and B constant. We want to discuss what is legal status.

  • greedy:
    • Assuming that only \ (n-\) th AB, legal situation is to have the front of each B \ (1 ... n \) th A
    • Suppose addition to AB, as well as \ (m \) a BA, and that in front of each B may have more than \ (n-\) th A, and have first or front B \ (1 ... n \) th A. Otherwise the back of a type B BA did not A.
    • A and B may constitute the back of the BA, the offset corresponds to one of A, B that next to the front just to have \ (1 ... n \) is not canceled A.
    • Therefore, less AB \ (n-\) is legal. When AB is equal to \ (the n-\) , means that only the last one is A, because if the last one is B, then B will have front \ (n + 1 \) a non-offset A.
    • A front how many B is the same reason.
  • DP

    • \ (DP [I] [J] \) , \ (I \) number of representatives of A, \ (J \) representative of the number of B. \ (dp \) represents the legitimate program.

    • Initialization, as previously described above have each A \ (1 ... m \) th B is legal, there is in front of each B \ (1 ... n \) th A legitimate

    • \(dp[i][0]=dp[0][j]=1\)

    • Not considered so much, can be derived
      \ [dp [i] [j ] = dp [i-1] [j] + dp [i] [j-1] \]

    • However, to exclude illegal situation

      • \ (0 \ leq ji \ leq m \) and \ (0 \ leq ij \ leq n \) is legal situation
      • Note that \ (m = \) and \ (n-= \) and \ (= 0 \) case
  • Or to say, ho brother best in the world

  • Code

    #include <bits/stdc++.h>
    
    #define ll long long
    using namespace std;
    const ll mod = 1e9 + 7;
    const ll N = 1e5 + 10;
    ll dp[2010][2010];
    
    int main() {
        ll n, m;
        while (scanf("%lld%lld", &n, &m) != EOF) {
            ll cnt = (n + m);
            for (int i = 0; i <= cnt; i++)
                for (int j = 0; j <= cnt; j++)
                    dp[i][j] = 0;
            for (ll i = 0; i <= cnt; i++) {
                dp[i][0] = dp[0][i] = 1;
            }
            for (ll i = 1; i <= cnt; i++) {
                for (ll j = 1; j <= cnt; j++) {
                    if (i == j) {
                        if (n)
                            dp[i][j] = (dp[i][j] + dp[i][j - 1]) % mod;
                        if (m)
                            dp[i][j] = (dp[i][j] + dp[i - 1][j]) % mod;
                    } else if (j > i) {
                        if (j - i < m)
                            dp[i][j] = ((dp[i][j] + dp[i - 1][j]) % mod + dp[i][j - 1]) % mod;
                        else if (j - i == m)
                            dp[i][j] = (dp[i][j] + dp[i][j - 1]) % mod;
                    } else if (i > j) {
                        if (i - j < n)
                            dp[i][j] = ((dp[i][j] + dp[i - 1][j]) % mod + dp[i][j - 1]) % mod;
                        if (i - j == n)
                            dp[i][j] = (dp[i][j] + dp[i - 1][j]) % mod;
                    }
                    //cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
                }
            }
            printf("%lld\n", dp[cnt][cnt] % mod);
        }
    
        return 0;
    

Guess you like

Origin www.cnblogs.com/smallocean/p/11209720.html