题目简介

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. android 定时提醒 - Notification

    定时弹出 demo ,代码如下: 1.MainActivity.java public class MainActivity extends Activity implements OnClickLi ...

  2. HMAC256 Token

    依赖包: <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</arti ...

  3. Spring+Mybatis整合的练手小项目(一)项目部署

    声明:教程是网上找的,代码是自己敲的 项目目录大致如下: 1. 首先创建Maven工程,在pom.xml中加入项目所需依赖: <?xml version="1.0" enco ...

  4. JAVA WEB中的Servlet过滤器

    实现一个Servlet过滤器,可以对用户登录情况进行控制.要求如下: 1)访问路径是admin下的资源,需要登录,如果用户没有登录,自动转向用户登录页面.用户登录成功后,再次访问admin下的资源不需 ...

  5. Python必备收藏!Pycharm 常用快捷键思维导图!

    本内容首发公众号[计算机视觉联盟],关注获取更多资料! 考虑到可能图片压缩,将思维导图的pdf和jpg版本都上传了百度云,大家可以下载打印一张A4纸,方便查询! 公众号后台回复关键词: 2019082 ...

  6. 月光宝盒之时间魔法--java时间的前生今世

    月光宝盒花絮 “曾经有一份真诚的爱情摆在我的面前,但是我没有珍惜,等到了失去的时候才后悔莫及,尘世间最痛苦的事莫过于此.如果可以给我一个机会再来一次的话,我会跟那个女孩子说我爱她,如果非要把这份爱加上 ...

  7. 微服务SpringCloud之zipkin链路追踪

    随着业务发展,系统拆分导致系统调用链路愈发复杂一个前端请求可能最终需要调用很多次后端服务才能完成,当整个请求变慢或不可用时,我们是无法得知该请求是由某个或某些后端服务引起的,这时就需要解决如何快读定位 ...

  8. ABP增加记录EFCore 生成数据库脚本日志到新的txt文件

    由于EFCore并没直接生成脚本到txt文件,故而自己画了点时间把实现记录下来,方便给大家参考. 0.安装Microsoft.Extensions.Logging.Debug,我这里是2.1.1版本. ...

  9. cp -rf 操作时依然会提示覆盖

    在linux上经常会使用cp -rf命令,该命令就是强制覆盖指定目录下的文件,但有时使用该命令依然会提示是否覆盖,cp命令的参数有如下一些: 参数说明: -a:此选项通常在复制目录时使用,它保留链接. ...

  10. JQuery 数组按指定长度分组

    JQuery方法 // 将data每3个一组进行分组 var data = ['法国','澳大利亚','智利','新西兰','西班牙','加拿大','阿根廷','美国','0','国产','波多黎各' ...