[Solution] Chinese chess title

Subject to the effect

  In one \ (n-\) OK \ (m \) on board the column ( \ (. 1 \ Leq n-, m \ Leq 100 \) ), requires each line up to the discharge of each column \ (2 \) pawn, seek program number $ \ BMOD 9,999,973
$.

answer

  More interesting dp.
  We can establish \ (dp [I] [i ] [j] [k] \) represents from \ (1 \) to the second \ (the I \) line, with a \ (I \) column only \ (1 \) pawn, there \ (J \) column only \ (2 \) two pieces, with a \ (K \) column only (0 \) \ total number of pieces of a program.
  Obviously \ (K \) may be made of \ (m \) and (I \) \ , \ (J \) to give, the dimensions may be eliminated. Of course, you can use the scroll optimized array.
  Because each row each column put up to (2 \) \ pawn so dp state transition equation only up to \ (5 \) cases, respectively, to enumerate, specifically to see the following code should be able to understand.

#include <iostream>

#define MAX_N 100
#define MAX_M 100
#define MOD 9999973

using namespace std;

int n, m;
long long dp[MAX_N | 1][MAX_N | 1][2];
// i:有1个棋子的列
// j:有2个棋子的列 
int ans;

inline int C(int x)
{
    return x * (x + 1) >> 1;
}

int main()
{
    cin >> n >> m;
    dp[0][0][1] = 1;
    dp[1][0][1] = m;
    dp[2][0][1] = C(m - 1);
    for(register int k = 2; k <= n; ++k)
    {
        for(register int i = 0; i <= m; ++i)
        {
            for(register int j = 0; i + j <= m; ++j)
            {
                dp[i][j][k & 1] = dp[i][j][k + 1 & 1];
                if(i) dp[i][j][k & 1] = (dp[i][j][k & 1] + dp[i - 1][j][k + 1 & 1] * (m - i - j + 1)) % MOD;
                if(i > 1) dp[i][j][k & 1] = (dp[i][j][k & 1] + dp[i - 2][j][k + 1 & 1] * C(m - i - j + 1)) % MOD;
                if(j) dp[i][j][k & 1] = (dp[i][j][k & 1] + dp[i + 1][j - 1][k + 1 & 1] * (i + 1)) % MOD;
                if(j > 1) dp[i][j][k & 1] = (dp[i][j][k & 1] + dp[i + 2][j - 2][k + 1 & 1] * C(i + 1)) % MOD;
                if(i && j) dp[i][j][k & 1] = (dp[i][j][k & 1] + dp[i][j - 1][k + 1 & 1] * i * (m - i - j + 1)) % MOD;
            }
        }
    }
    for(register int i = 0; i <= m; ++i)
    {
        for(register int j = 0; i + j <= m; ++j)
        {
            ans += dp[i][j][n & 1];
            // cout << m - i - j << " " << i << " " << j << ": " << dp[i][j][n & 1] << endl; // debug
            if(ans >= MOD) ans -= MOD;
        }
    }
    cout << ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/kcn999/p/11361427.html