看见第一眼觉得是状压 \(\text{DP}\)?观察数据范围发现不可做

那按照最常规思路设状态试试?

设状态为\(dp[i][j]\)表示\(i*j\)的棋盘的方案数

好像转移不了欸 要不再来一维?

\(dp[i][j][k]\)表示。。。 还是不行啊

要求的就是每行,每列都不能有三个及其以上的炮

所以一共就只有三种状态:没有,一个炮,两个炮

但是列与列之间交换位置是完全没有问题的

所以设状态为 \(dp[i][j][k]\) 做了 \(i\) 行,有 \(j\) 列放了一个炮,有 \(k\) 列放了两个炮

如果第 \(i\) 行不放,则有

\[dp[i][j][k]+=dp[i-1][j][k]
\]

放一个,则上一个状态一定是\(dp[i-1][j-1][k]\) 或者是 \(dp[i-1][j+1][k-1]\),由简单组合数学可得

\[dp[i][j][k]+=(m-k-(j-1))\cdot dp[i-1][j-1][k]+(j+1) \cdot dp[i-1][j+1][k-1]
\]

放两个,那一定从 \(dp[i-1][j][k-1]\) 或者 \(dp[i-1][j-2][k]\) 或者 \(dp[i-1][j+2][k-2]\)转移而来

则有(自己推式子感觉真好)

\[dp[i][j][k]+=(m-j-(k-1)) \cdot j\cdot dp[i-1][j][k-1]\\
dp[i][j][k]+={C}_{m-k-(j-2)}^{2} \cdot dp[i-1][j-2][k]\\
dp[i][j][k]+={C}_{j+2}^{2}*dp[i-1][j+2][k-2]\\
\]

然后就是处理边界问题了

估计要开 \(long\ long\)(狗头

贴代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll p=9999973;
const ll maxn=1e2+10;
ll n,m,dp[maxn][maxn][maxn];
ll C(ll num)
{
return num*(num-1)/2;
}
int main()
{
scanf("%lld%lld",&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;j+k<=m;++k)
{
if(i-1>=0) dp[i][j][k]+=dp[i-1][j][k];
if(k-1>=0) dp[i][j][k]+=(j+1)*dp[i-1][j+1][k-1];
if(j-1>=0) dp[i][j][k]+=(m-k-(j-1))*dp[i-1][j-1][k];
if(k-2>=0) dp[i][j][k]+=C(j+2)*dp[i-1][j+2][k-2];
if(k-1>=0) dp[i][j][k]+=(m-j-(k-1))*j*dp[i-1][j][k-1];
if(j-2>=0) dp[i][j][k]+=C(m-k-(j-2))*dp[i-1][j-2][k];
dp[i][j][k]%=p;
}
ll ans=0;
for(int i=0;i<=m;++i)
for(int j=0;i+j<=m;++j)
ans=(ans+dp[n][i][j])%p;
printf("%lld\n",(ans+p)%p);
return 0;
}

\(\text{End.}\)

Luogu P2051「AHOI2009」中国象棋的更多相关文章

  1. BZOJ 1801: [Ahoi2009]chess 中国象棋( dp )

    dp(i, j, k)表示考虑了前i行, 放了0个炮的有j列, 放了1个炮的有k列. 时间复杂度O(NM^2) -------------------------------------------- ...

  2. 【BZOJ1801】【AHOI2009】中国象棋(动态规划)

    [BZOJ1801][AHOI2009]中国象棋(动态规划) 题面 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个 ...

  3. BZOJ_1801_[Ahoi2009]chess 中国象棋_DP

    BZOJ_1801_[Ahoi2009]chess 中国象棋_DP Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像 ...

  4. 【BZOJ1801】[Ahoi2009]chess 中国象棋 DP

    [BZOJ1801][Ahoi2009]chess 中国象棋 Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮 ...

  5. BZOJ1801 Ahoi2009 chess 中国象棋 【DP+组合计数】*

    BZOJ1801 Ahoi2009 chess 中国象棋 Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行 ...

  6. Bzoj 1081 [Ahoi2009] chess 中国象棋

    bzoj 1081 [Ahoi2009] chess 中国象棋 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1801 状态比较难设,的确 ...

  7. BZOJ1801 [Ahoi2009]chess 中国象棋(DP, 计数)

    题目链接 [Ahoi2009]chess 中国象棋 设$f[i][j][k]$为前i行,$j$列放了1个棋子,$k$列放了2个棋子的方案数 分6种情况讨论,依次状态转移. #include <b ...

  8. bzoj1801: [Ahoi2009]chess 中国象棋(DP)

    1801: [Ahoi2009]chess 中国象棋 题目:传送门 题解: 表示自己的DP菜的抠脚 %题解... 定义f[i][j][k]表示前i行 仅有一个棋子的有j列 有两个棋子的有k个 的方案数 ...

  9. LOJ #2116 Luogu P3241「HNOI2015」开店

    好久没写数据结构了 来补一发 果然写的时候思路极其混乱.... LOJ #2116 Luogu P3241 题意 $ Q$次询问,求树上点的颜色在$ [L,R]$中的所有点到询问点的距离 强制在线 询 ...

随机推荐

  1. Linxu 修改主机名

    方法一: # hostname NEW_NAME <这种方法只对当前系统有效,重启后无效> 方法二: # hostnamectl set-hostname NEW_NAME:设定主机名,永 ...

  2. 【greys使用】阿里greys在线诊断工具

    Greys是一个Java进程的异常诊断工具,可以在不停止程序的前提下,对一些问题进行检测.这个框架主要是采用Java的探针技术,可以做到动态修改java的字节码技术.前提是Jdk版本6+.(prema ...

  3. CVPR2019:无人驾驶3D目标检测论文点评

    CVPR2019:无人驾驶3D目标检测论文点评 重读CVPR2019的文章,现在对以下文章进行点评. Stereo R-CNN based 3D Object Detection for Autono ...

  4. 微调BERT:序列级和令牌级应用程序

    微调BERT:序列级和令牌级应用程序 Fine-Tuning BERT for Sequence-Level and Token-Level Applications 为自然语言处理应用程序设计了不同 ...

  5. Nginx 配置文件介绍

    目录 1.1 常用命令 1.2 Nginx的配置文件结构 1.3 Nginx的全局配置 1.4 HTTP服务器配置 1.5 HttpGzip配置 1.6 负载均衡配置 1.7 server虚拟主机配置 ...

  6. Mysql数据库值的添加、修改、删除及清空

    3.MySQL数据管理 第一种方式:不太建议,看起来复杂些 -- 学生表的 gradeid 字段,要去引用 年级表的 gradeid -- 定义外键key -- 给这个外键添加约束,(执行引用),RE ...

  7. 【VBA】测试程序运行时间,延时方法

    测试程序运行时间 Dim start As Date start = Now() Dim i As Long For i = 0 To 10000000 ' 10 million Next Debug ...

  8. 消失之物(背包DP)(容斥或分治)

    容斥做法: 首先n^2搞出f[i][j]第i个物品,j体积的方案数. 去除每个物品贡献: 设个g[i][j]表示当i不选,j体积方案数(注意不是此时的范围相对于全局,而不是1---i) 那么我们用到一 ...

  9. 【题解】localmaxima 数论

    # T749 localmaxima 权限限制没有超链接 题目描述 Description 给出一个排列,若其中一个数比它前面的数都大,则称为localmaxima数,求一个随机排列中localmax ...

  10. string转char*/char[]

    转char* 主要有三种方法可以将str转换为char*类型,分别是:data(); c_str(); copy(); 1.data() data()仅返回字符串内容,而不含有结束符'\0' std: ...