题目简介

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. vuex-class用法

    vuex-class可以包装vuex的写法,使代码简化 Installation $ npm install --save vuex-class Example import Vue from 'vu ...

  2. FreeSql (十五)查询数据

    FreeSql在查询数据下足了功能,链式查询语法.多表查询.表达式函数支持得非常到位. IFreeSql fsql = new FreeSql.FreeSqlBuilder() .UseConnect ...

  3. CODESYS添加target

    1.主界面进入Tools 2.Install,选择安装包

  4. 利用IntelliJ IDEA与Maven开发scala程序,并打包提交到spark集群

    https://zhuanlan.zhihu.com/p/23141509 https://blog.csdn.net/u011470552/article/details/54564636 http ...

  5. Hadoop 之 MapReduce原理

    1.什么是MapReduce 答:简而言之,就是将一个大任务分成多个小的子任务(Map),并行执行后,合并结果(Reduce).下面举一个纸牌得栗子  2.MapReduce的运行流程  3.JobT ...

  6. LeetCode 230.二叉树中第k小的元素

    题目: 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 说明:你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数. 这道题在leetCode上难 ...

  7. 抓住那只牛!Catch That Cow POJ-3278 BFS

    题目链接:Catch That Cow 题目大意 FJ丢了一头牛,FJ在数轴上位置为n的点,牛在数轴上位置为k的点.FJ一分钟能进行以下三种操作:前进一个单位,后退一个单位,或者传送到坐标为当前位置两 ...

  8. liunx帮助whatis使用方法

           liunx帮助             获取帮助的能力决定了技术的能力! 1.whatis ♢只显示命令的简短描述,相对功能比较单一. [09:42:22 root@centos ~]# ...

  9. Mycat 配置文件schema.xml

    1.介绍 schema.xml 作为 MyCat 中重要的配置文件之一,管理着 MyCat 的逻辑库.表.分片规则. DataNode 以及 DataSource. 2.schema相关标签 sche ...

  10. jQuery常用方法(六)-jQuery 工具

    JQuery Utilities 方法说明 jQuery.browser .msie 表示ie jQuery.browser.version 读取用户浏览器的版本信息 jQuery.boxModel ...