博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P2051 中国象棋
阅读量:6067 次
发布时间:2019-06-20

本文共 1448 字,大约阅读时间需要 4 分钟。

题目描述

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

输入输出格式

输入格式:

 

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

 

输出格式:

 

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

 

  • 思路:用f[i][j][k]表示前i行,有j列只有1个棋子,有k列有2个棋子的方案数
  • 代码:
#include 
#include
#include
#include
#include
using namespace std;#define res register inttypedef 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<
<

  

转载于:https://www.cnblogs.com/wmq12138/p/10447692.html

你可能感兴趣的文章
解决Retrofit多BaseUrl及运行时动态改变BaseUrl(二)
查看>>
【深入浅出MyBatis笔记】插件
查看>>
sublime常用基础插件合集
查看>>
React 重温之Render Props
查看>>
聊聊JerseyEurekaHttpClient的参数
查看>>
js 粘贴图片的应用(clipboardData)
查看>>
5分钟解决小程序的微信支付
查看>>
SpringBoot里的@Import使用
查看>>
Mac 配置Apache服务器详解
查看>>
从Rancher 1.6到2.0:术语及概念变化对比
查看>>
一次线上问题的排查解决过程
查看>>
ES5与ES6字符串方法总结
查看>>
基于Django开发的简洁博客系统
查看>>
Lintcode187 solution 题解
查看>>
nadejs进程管理小记
查看>>
WPF:数据绑定示例总结(2)
查看>>
UVa 201 Squares
查看>>
PHP实现markdown文档管理工具
查看>>
leetcode 628 Maximum Product of Three Numbers
查看>>
ELSE 技术周刊(2017.12.18期)
查看>>