HYSBZ - 4806 炮——dp

dp(r,i,j)表示第r行有0个炮的列数为i,有1个炮的列数为j,有2个炮的列数为m-i-j时的情况数

决策有三个,当前行放0个炮,放1个炮,放2个炮

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 110;
const int mod = 999983;
typedef long long ll;
int n, m;
ll dp[maxn][maxn][maxn];
void solve() {
    memset(dp, 0, sizeof(dp));
    dp[0][m][0] = 1;
    for (int r = 0; r < n; r++) {
        for (int i = 0; i <= m; i++) {
            for (int j = 0; j + i <= m; j++) {
                if (!dp[r][i][j]) continue;
                dp[r+1][i][j] = (dp[r+1][i][j] + dp[r][i][j]) % mod;
                if (i >= 1) dp[r+1][i-1][j+1] = (dp[r+1][i-1][j+1] + dp[r][i][j] * i) % mod;
                if (j >= 1) dp[r+1][i][j-1] = (dp[r+1][i][j-1] + dp[r][i][j] * j) % mod;
                if (i >= 2) dp[r+1][i-2][j+2] = (dp[r+1][i-2][j+2] + dp[r][i][j] * i * (i - 1) / 2) % mod;
                if (i >= 1) dp[r+1][i-1][j] = (dp[r+1][i-1][j] + dp[r][i][j] * i * j) % mod;
                if (j >= 2) dp[r+1][i][j-2] = (dp[r+1][i][j-2] + dp[r][i][j] * j * (j - 1) / 2) % mod;
            }
        }
    }
}
int main() {
    while (~scanf("%d%d", &n, &m)) {
        solve();
        int ans = 0;
        for (int i = 0; i <= m; i++) {
            for (int j = 0; j + i <= m; j++) {
                ans = (ans + dp[n][i][j]) % mod;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/80195585