[BZOJ] 4806 炮

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 793 Solved: 392
[Submit][Status][Discuss]
Description
众所周知,双炮叠叠将是中国象棋中很厉害的一招必杀技。炮吃子时必须隔一个棋子跳吃,即俗称"炮打隔子"。
炮跟炮显然不能在一起打起来,于是rly一天借来了许多许多的炮在棋盘上摆了起来……他想知道,在N×M的矩形
方格中摆若干炮(可以不摆)使其互不吃到的情况下方案数有几种。
棋子都是相同的。
Input
一行,两个正整数N和M。
N<=100,M<=100
Output
一行,输出方案数mod 999983。
Sample Input
1 3
Sample Output
7
HINT
Source
By FancyCoder
[Submit][Status][Discuss]

大分类讨论,细心。

#include<iostream>
#include<cstdio>
#define rsh now%=MOD
#define int long long
using namespace std;
const int MAXN=105;
const int MOD=999983;
int f[2][MAXN][MAXN];
int n,m;
int calc(int x){
return (x*(x-1)/2)%MOD;
}
signed main(){
cin>>n>>m;
f[0][0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){//1
for(int k=0;k+j<=m;k++){//2
int &now=f[i&1][j][k];
now=f[(i-1)&1][j][k];
if(k>=1) now+=f[(i-1)&1][j+1][k-1]*(j+1);
if(k>=2) now+=f[(i-1)&1][j+2][k-2]*calc(j+2);
if(j>=1) now+=f[(i-1)&1][j-1][k]*(m-j-k+1);
if(j>=2) now+=f[(i-1)&1][j-2][k]*calc(m-j-k+2);
if(k>=1) now+=f[(i-1)&1][j][k-1]*(m-j-k+1)*j;
rsh;
}
}
}
int ans=0;
for(int i=0;i<=m;i++){
for(int j=0;i+j<=m;j++){
ans+=f[n&1][i][j];
}ans%=MOD;
}
cout<<ans<<endl;
return 0;
}
posted @   GhostCai  阅读(120)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示