洛谷P2051 [AHOI2009]中国象棋

开始没想出来QAQ…
注意初始边界,以及我们只需关心当前行要放几个炮,与炮的位置无关
代码:

#include<cstdio>
using namespace std;
const int mod = 9999973;
long long F[105][105][105];
long long C(int x)
{
    return x * (x - 1) >> 1;
}
inline void update(long long &a,long long b)
{
    a = (a + b) % mod;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n,m;
    scanf("%d%d",&n,&m);
    F[0][0][0] = 1;
    for(int i = 0;i < n; ++i)
        for(int j = 0;j <= m; ++j)
            for(int k = 0;k + j  <= m; ++k)
            {
                update(F[i+1][j][k], F[i][j][k]);
                if(j - 1 >= 0) update(F[i+1][j-1][k+1], F[i][j][k] * j);
                if(m - k - j >= 1) update(F[i+1][j+1][k], F[i][j][k] * (m - k - j));
                if(j - 2 >= 0) update(F[i+1][j-2][k+2], F[i][j][k] * C(j));
                if(m - k - j >= 2) update(F[i+1][j+2][k], F[i][j][k] * C(m - k - j));
                if(j >= 1 && m - k - j >= 1)update(F[i+1][j][k+1], F[i][j][k] * j * (m - k - j));
            }
    long long ans = 0;
    for(int i = 0;i <= m;++i)
        for(int j = 0; j + i <= m; ++j)
            update(ans,F[n][i][j]);
    printf("%lld",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/guangheli/p/9845202.html