题目简介

n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100

题目分析

算法考虑

考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压Dp

算法分析

设dp[i][j][k]表示放了前i行,j列有1个棋子,k列有两个棋子

那么0个棋子就是m-j-k

然后就可以分类讨论了

情况一

第i行不放棋子:直接继承上一行状态,有:f[i][j][k]=f[i-1][j][k]

情况二

第i行只放一个棋子:

1、该棋放在只有一个棋的列上

有f[i][j][k]=f[i-1][j+1][k-1]*(j+1) 因为对于前i-1行,有一个棋子的一列少了1,而因为放置棋子,有两个的棋子又多了一列,又因为该棋子可以随便放在只有一个棋的列上,所以要乘(j+1)

有:f[i][j][k]=f[i-1][j+1][k-1]*(j+1)

2、该棋放在没有棋子的列上

同理,即f[i-1][j-1][k]可以转移到f[i][j][k]

又因为我在空列中的任何一列放置这个棋子.

所以要×(m-j-k+1)

有:f[i][j][k]=f[i][j][k]+f[i-1][j-1][k]*(m-j-k+1);

情况三

第i行放两个棋子

1、放在一列一个的,一列没有棋子的列上

一个没有棋子的列会变成一个有一个棋子的列,而一个有一个棋子的列会变成一个有两个棋子的列。

此时我们发现,

有一个棋子的列的数量不会变,因此第二维依旧为j,

又因为我们会新增一个有两个棋子的列,所以我们需要从k-1转移过来.

有:f[i][j][k]=f[i][j][k]+f[i-1][j][k-1]*j*(m-j-k+1)

2、放在两个没有棋子的列上

会增加两个新的有一个棋子的列.

因此我们需要从j-2转移过来.

而两个棋子的列的数量并不会改变,所以依旧为k

最后乘C(2,m-k-j+2),因为从没有棋子的列中任选两个

有:f[i][j][k]=f[i][j][k]+f[i-1][j-2][k]*C(2,m-k-j+2)

3、放在两个有一个棋子的列上

这两个有一个棋子的列都会变成有两个子的列.

即j+2变成j,从k-2变成k

最后乘C(2,j+2)因为从有一个棋子的列中任选两个

有:f[i][j][k]=f[i][j][k]+f[i-1][j+2][k-2]*C(2,j+2)

代码

#include<bits/stdc++.h>
#define re register
#define ll long long
using namespace std;
inline int read()
{
int k=1,sum=0;
char c=getchar();
for(;c<'0' || c>'9';c=getchar()) if(c=='-') k=-1;
for(;c>='0' && c<='9';c=getchar()) sum=sum*10+c-'0';
return sum*k;
}
int n,m;
const int MOD=9999973,N=1e2+10;
ll f[N][N][N];
inline int C(int x){
return ((x*(x-1))/2)%MOD;
}
int main()
{
n=read();m=read();f[0][0][0]=1;
for(re int i=1;i<=n;++i){
for(re int j=0;j<=m;++j){
for(re int k=0;k<=m-j;++k){
f[i][j][k]=f[i-1][j][k];
if(k>0 && j+1<=m) f[i][j][k]=(f[i][j][k]+f[i-1][j+1][k-1]*(j+1))%MOD;
if(j>0) f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k]*(m-j-k+1))%MOD;
if(k>0) f[i][j][k]=(f[i][j][k]+f[i-1][j][k-1]*j*(m-j-k+1))%MOD;
if(k>1) f[i][j][k]=(f[i][j][k]+f[i-1][j+2][k-2]*C(j+2))%MOD;
if(j>1) f[i][j][k]=(f[i][j][k]+f[i-1][j-2][k]*C(m-k-j+2))%MOD;
f[i][j][k]%=MOD;
}
}
}
int ans=0;
for(re int j=0;j<=m;++j)
for(re int k=0;k<=m-j;++k)
ans=(ans+f[n][j][k])%MOD;
cout<<ans;
return 0;
}

洛谷P2051 [AHOI2009] 中国象棋(状压dp)的更多相关文章

  1. 洛谷 P2051 [AHOI2009]中国象棋 解题报告

    P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...

  2. [Luogu P2051] [AHOI2009]中国象棋 (状压DP->网格DP)

    题面 传送门:https://www.luogu.org/problemnew/show/P2051 Solution 看到这题,我们不妨先看一下数据范围 30pt:n,m<=6 显然搜索,直接 ...

  3. 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP

    P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...

  4. [洛谷P2051] [AHOI2009]中国象棋

    洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...

  5. 洛谷P2051 [AHOI2009]中国象棋(dp)

    题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...

  6. 洛谷 P2051 [AHOI2009]中国象棋

    题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...

  7. 【题解】洛谷P3959 [NOIP2017TG] 宝藏(状压DP+DFS)

    洛谷P3959:https://www.luogu.org/problemnew/show/P3959 前言 NOIP2017时还很弱(现在也很弱 看出来是DP 但是并不会状压DP 现在看来思路并不复 ...

  8. 洛谷 P1278 单词游戏 【状压dp】

    题目描述 Io和Ao在玩一个单词游戏. 他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致. 游戏可以从任何一个单词开始. 任何单词禁止说两遍,游戏中只 ...

  9. 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]

    题目传送门 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图 ...

随机推荐

  1. CCF 模拟试题——出现次数最多的数 官方答案解析及自己写的正确答案

    前几天知道的CCF计算机职业资格认证考试,觉得好像比软考含金量高一些,就去了解了一下,做了模拟试题中的 “出现次数最多的数” 这道题,我的算法和官方答案算法不同,个人觉得觉得官方的好一点,没那么繁琐, ...

  2. stm32 新建工程

    先新建六个文件夹. Consis:启动文件等 Fwlib:inc.src文件夹 Hardware:存放驱动 Mdk:工程文件 User:main函数等

  3. Flask学习之旅--还是数据库(sqlacodegen + SQL Alchemy)

    一.写在前面 其实之前已经写过一篇关于 Flask 中使用数据库的博客了,不过那一篇博客主要是记录我在使用 Flask + MySQL8.0 时所遇到的一些问题(如果用的不是 MySQL8.0估计就没 ...

  4. 控制执行流程之ForEach语法

    1.定义 : 一种更加简洁的for语法,用于数组和容器===>>>foreach,无需创建int类型变量对被访问项构建的序列进行计数. 2.经典应用:  对于数组的初始化,如果选用f ...

  5. netty源码解解析(4.0)-22 ByteBuf的I/O

        ByteBuf的I/O主要解决的问题有两个: 管理readerIndex和writerIndex.这个在在AbstractByteBuf中解决. 从内存中读写数据.ByteBuf的不同实现主要 ...

  6. mysql备份脚本并保留7天

    脚本需求: 每天备份mysql数据库,保留7天的脚本. 存放在/opt/dbbak目录中. 脚本名称为database_xxxx-xx-xx.sql 脚本内容: #!/bin/bash export ...

  7. jenkins之插件下载方法

    jenkins插件下载方法有两种,在线下载和离线下载方式 在线下载 就是在安装好了jenkins之后,进入jenkins的插件管理页面,搜索想要的插件,点击安装即可 例如:安装git插件 问题:有时候 ...

  8. 【THE LAST TIME】彻底吃透 JavaScript 执行机制

    前言 The last time, I have learned [THE LAST TIME]一直是我想写的一个系列,旨在厚积薄发,重温前端. 也是给自己的查缺补漏和技术分享. 欢迎大家多多评论指点 ...

  9. Hadoop点滴-Hadoop的IO

    Hadoop自带一套原子操作用于数据的I/O操作. 如果系统中需要处理的数据量达到Hadoop的处理极限时,数据被损害的概率还是很高的 检测数据是否被损害的常见措施是,在数据第一次被引进系统时,计算校 ...

  10. maven私服 nexus 的安装与使用

    简介 私服不是Maven的核心概念,它仅仅是一种衍生出来的特殊的Maven仓库.通过建立自己的私服,就可以降低中央仓库负荷.节省外网带宽.加速Maven构建.自己部署构建等,从而高效地使用Maven. ...