• 2018.10.23-dtoi-2004:象棋Chess(Chess)


    题目描述:

    在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮。
    请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧.

    输入:

    一行包含两个整数N,M,中间用空格分开.

    输出:

    输出所有的方案数,由于值比较大,输出其mod 9999973

    数据范围:

    100%的数据中N,M不超过100
    50%的数据中,N,M至少有一个数不超过8
    30%的数据中,N,M均不超过6

    算法标签:DP

    思路:

    一开始可能会想到状压DP,但是只有30分。考虑dp,用f[i][j][k]表示在前一行,有j行放了1个炮,k行放了两个炮。

    考虑转移式子:...太多了看代码把

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define LL long long
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=105,p=9999973;LL f[N][N][N],ans;int n,m;
    il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;}
    il LL cal(int x){return ((LL)x*(LL)(x-1)/2ll)%p;}
    int main()
    {
        n=read();m=read();f[0][0][0]=1;
        for(int i=1;i<=n;i++)for(int j=0;j<=m;j++)for(int k=0;k+j<=m;k++){
            (f[i][j][k]+=f[i-1][j][k])%=p;
            if(k>=1)(f[i][j][k]+=f[i-1][j+1][k-1]*(LL)(j+1))%=p;
            if(j>=1)(f[i][j][k]+=f[i-1][j-1][k]*(LL)(m-k-j+1)%p)%=p;
            if(j>=2)(f[i][j][k]+=f[i-1][j-2][k]*cal(m-k-j+2)%p)%=p;
            if(k>=2)(f[i][j][k]+=f[i-1][j+2][k-2]*cal(j+2)%p)%=p;
            if(k>=1)(f[i][j][k]+=f[i-1][j][k-1]*(LL)j*(LL)(m-j-k+1)%p)%=p;
        }
        for(int i=0;i<=m;i++)for(int j=0;j+i<=m;j++)(ans+=f[n][i][j])%=p;
        printf("%lld
    ",ans);
      return 0;
    }
    View Code
  • 相关阅读:
    Proj THUDBFuzz Paper Reading: PMFuzz: Test Case Generation for Persistent Memory Programs
    入围 WF 后训练记
    算法竞赛历程
    2021 多校 杭电 第十场
    2021 多校 杭电 第九场
    2021 多校 牛客 第十场
    2021 多校 牛客 第九场
    2021 多校 杭电 第八场
    2021 多校 杭电 第六场
    2021 多校 杭电 第七场
  • 原文地址:https://www.cnblogs.com/Jessie-/p/9843892.html
Copyright © 2020-2023  润新知