zoukankan      html  css  js  c++  java
  • BZOJ 4806 : 炮

    题目链接

    题意:炮在同一行或是同一列超过三个就可以出现一个吃掉另一个的情况,求在n*m的棋盘上放置炮且两两不可吃的情况总数。

    用dp的方法来完成计数,可以考虑这样一个状态,枚举到第x行,共有 a个“含2个炮的列”, b个“含1个炮的列”, c个“含0个炮的列”,注意到a+b+c等于定值,显然这是可以优化的。基本思路大概这样。

    dp[i][j][k]表示前i行里,具有{有j个“含1个炮的列”, k个“含2个炮的列”}性质的情况总数

    最后求ans时,要对dp[n][][]求总和

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    
    const int mod=999983;
    const int N=105;
    
    int n,m;
    LL dp[N][N][N];
    
    int cal(int x)
    {
        return x*(x-1)/2%mod;
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            dp[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++)
                    {
                        dp[i][j][k]=dp[i-1][j][k];
                        if(j>=1) dp[i][j][k]=(dp[i][j][k]+dp[i-1][j-1][k]*(m-k-j+1))%mod;
                        if(j>=2) dp[i][j][k]=(dp[i][j][k]+dp[i-1][j-2][k]*cal(m-k-j+2))%mod;
                        if(k>=1) dp[i][j][k]=(dp[i][j][k]+dp[i-1][j+1][k-1]*(j+1))%mod;
                        if(k>=1) dp[i][j][k]=(dp[i][j][k]+dp[i-1][j][k-1]*(m-k-j+1)%mod*j)%mod;
                        if(k>=2) dp[i][j][k]=(dp[i][j][k]+dp[i-1][j+2][k-2]*cal(j+2))%mod;
                    }
            int ans=0;
            for(int i=0;i<=m;i++)
                for(int j=0;i+j<=m;j++)
                    ans=(ans+dp[n][i][j])%mod;
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    web前端常见面试题
    pyhton课堂随笔-基本画图
    安装和启动json-server
    Idea破解注册码
    MongoDB基本增删改查
    MogonDB安装及配置
    python和jupyter安装
    web中静态资源和动态资源的概念及区别
    nodejs基础(三)
    C#进程、线程、CPU
  • 原文地址:https://www.cnblogs.com/Just--Do--It/p/7308141.html
Copyright © 2011-2022 走看看