题目简介

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. 一步一步搞安卓开发(AndroidStudio)

    一.前言 好长时间没做过Android应用开发了,由于工作需要,又要开始做这一块了.记得之前都是用Eclipse+ADT+ADK来开发的,官网上下载个adt-bundle就可以了,现在官方已经不更新了 ...

  2. 垃圾佬的旅游III(Hash + 暴力)

    题目链接:http://120.78.128.11/Problem.jsp?pid=3445 最开始的思路就是直接暴力求解,先把所有的数值两两存入结构体,再从小到大枚举.用二分的思路去判断数值以及出现 ...

  3. SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)

    准备工作 环境准备 JAVA版本 java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121 ...

  4. DirectX12 3D 游戏开发与实战第四章内容(下)

    Direct3D的初始化(下) 学习目标 了解Direct3D在3D编程中相对于硬件所扮演的角色 理解组件对象模型COM在Direct3D中的作用 掌握基础的图像学概念,例如2D图像的存储方式,页面翻 ...

  5. prometheus告警模块alertmanager注意事项(QQ邮箱发送告警)

    配置alertmanager的时候,都是根据网上的教程来配置的. 因为我是用QQ邮箱来发送告警的,所以alertmanager.yml的邮箱配置如下: global: resolve_timeout: ...

  6. Day 25 网络基础

    1:网络的重要性: 所有的系统都有网络! 我们的生活已经离不开网络. 运维生涯50%的生产故障都是网络故障! 2:教室这么多的电脑如何上网的? 网卡(mac地址) 有线(双绞线传播电信号)双向,同时收 ...

  7. 使用Hexo搭建个人博客并部署到GitHub或码云上全过程

    一.前言 如上图所示:GitHub有Github Pages,而码云也有码云 Pages 1.Github Pages或Gitee Pages是什么呢? Github Pages或者Gitee Pag ...

  8. mysql5.6.27压缩版安装配置指南【个人总结】

      1..下载准备压缩包   360云盘下载地址: https://yunpan.cn/cPKyugkUcDEmP  访问密码 375b   2.解压缩,将压缩版解压到D盘 D:\mysql-5.6. ...

  9. MySQL 中间件汇总比较

    360 Atlas 较为活跃,Atlas 是由 360 Web平台部基础架构团队开发维护的一个基于 MySQL 协议的数据中间层项目.它是在mysql-proxy 0.8.2版本的基础上,对其进行了优 ...

  10. 正睿OI国庆DAY2:图论专题

    正睿OI国庆DAY2:图论专题 dfs/例题 判断无向图之间是否存在至少三条点不相交的简单路径 一个想法是最大流(后来说可以做,但是是多项式时间做法 旁边GavinZheng神仙在谈最小生成树 陈主力 ...