• P2051 中国象棋


    P2051 中国象棋

    题目描述

    这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法。大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子。你也来和小可可一起锻炼一下思维吧!

    输入输出格式

    输入格式:

    一行包含两个整数N,M,之间由一个空格隔开。

    输出格式:

    总共的方案数,由于该值可能很大,只需给出方案数模9999973的结果。

    • 思路:用f[i][j][k]表示前i行,有j列只有1个棋子,有k列有2个棋子的方案数
    • 代码:
    #include <cstdio>
    #include <algorithm>
    #include <cctype>
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    #define res register int
    typedef long long LL;
    const int N=110;
    const int mod=9999973;
    int n,m;
    LL f[N][N][N];//前i行已经放好,其中只放了一个的列有j列,放了两个的列有k列 
    inline int calc(int x)//在x个数中选2个的方案数 
    {
    	return x*(x-1)/2;
    }
    
    int main()
    {
    	scanf("%d %d",&n,&m);
    	f[0][0][0]=1;
    	for(res i=0 ; i<=n-1 ; ++i)
    	for(res j=0 ; j<=m ; ++j)
    	for(res k=0 ; k+j<=m ; ++k)
    		if(f[i][j][k])
    		{
    			f[i+1][j][k]=(f[i+1][j][k]+f[i][j][k])%mod;
    			
    			if(m-j-k>=1)//放1个在有空余的列 
    				f[i+1][j+1][k]=(f[i+1][j+1][k]+(m-j-k)*f[i][j][k])%mod;	
    			if(j>=1)//放1个在已经有 
    				f[i+1][j-1][k+1]=(f[i+1][j-1][k+1]+j*f[i][j][k])%mod;
    			if(m-j-k>=2)
    				f[i+1][j+2][k]=(f[i+1][j+2][k]+calc(m-j-k)*f[i][j][k])%mod;
    			if(m-j-k>=1 && j>=1)//放2个,1个在已经有的,另一个在没有的 
    				f[i+1][j][k+1]=	(f[i+1][j][k+1]+j*(m-j-k)*f[i][j][k])%mod;
    			if(j>=2)
    				f[i+1][j-2][k+2]=(f[i+1][j-2][k+2]+calc(j)*f[i][j][k])%mod;
    		}		
    	LL ans=0;
    	for(res i=0 ; i<=m ; ++i)
    		for(res j=0 ; i+j<=m ; ++j)
    			ans=(ans+f[n][i][j])%mod;
    	cout<<ans<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    idea 配置 maven 项目
    idea 配置普通web项目
    idea java.lang.OutOfMemoryError: PermGen space
    idea checkout 项目
    物理机自动化装机实现
    prometheus node_exporter相关监控指标
    nginx Linux内核参数的优化
    《高性能 Go 代码工坊》中译
    docker仓库资源的地址修改
    influxdb-1.7.8(centos 7) 部署
  • 原文地址:https://www.cnblogs.com/wmq12138/p/10447692.html
Copyright © 2020-2023  润新知