...

  • 题目:
  • 题意:
  • 分析:
  • 代码:

题目:

洛谷传送门


题意:

有一张 n ∗ m n*m n∗m的图,在这其中放置若干象棋炮兵,在它们不会互相攻击的情况下,求有多少合法方案


分析:

因为题目中已经明确告诉我们是象棋炮兵,所以每一行和每一列都至多放置 2 2 2个炮兵
针对炮兵每行每列放置的数量极其有限,我们想出了方程 f i , j , k f_{i,j,k} fi,j,k​,表示已经放好了前 i i i行,其中有 j j j列放了一个炮兵,有 k k k列放了两个炮兵
随着行数的递增,我们发现会有 5 5 5中可能的情况出现:
1. 1. 1.新的一行什么也不做:
f i , j , k + = f i − 1 , j , k f_{i,j,k}+=f_{i-1,j,k} fi,j,k​+=fi−1,j,k​
2. 2. 2.新的一行只放一个炮兵
( 1 ) \ (1)  (1)我们在没有炮兵的一列放上,也就是多了一列放了一个炮兵的列:
f i , j + 1 , k + = f i − 1 , j , k ∗ ( m − j − k ) ( m − j − k > 0 ) f_{i,j+1,k}+=f_{i-1,j,k}*(m-j-k) (m-j-k>0) fi,j+1,k​+=fi−1,j,k​∗(m−j−k)(m−j−k>0)
( 2 ) \ (2)  (2)我们在只有一个炮兵的列放上,也就是少了一列只放一个的,多了一个放两个的列:
f i , j − 1 , k + 1 + = f i − 1 , j , k ∗ j ( j > 0 ) f_{i,j-1,k+1}+=f_{i-1,j,k}*j(j>0) fi,j−1,k+1​+=fi−1,j,k​∗j(j>0)
3. 3. 3.新的一行放两个炮兵
( 1 ) \ (1)  (1)两个都放在空列上,即多了两列只放一个的:
f i , j + 2 , k + = f i − 1 , j , k ∗ C m − j − k 2 ( m − j − k > 1 ) f_{i,j+2,k}+=f_{i-1,j,k}*C_{m-j-k}^2(m-j-k>1) fi,j+2,k​+=fi−1,j,k​∗Cm−j−k2​(m−j−k>1)
( 2 ) \ (2)  (2)两个都放在放了一个的上面,即少了两列只放一个的,多了两列放两个的:
f i , j − 2 , k + 2 + = f i − 1 , j , k ∗ C j 2 ( j > 1 ) f_{i,j-2,k+2}+=f_{i-1,j,k}*C_j^2(j>1) fi,j−2,k+2​+=fi−1,j,k​∗Cj2​(j>1)
( 3 ) \ (3)  (3)一个放在空列上,一个放在只有一个的上面:
f i , j , k + 1 + = f i − 1 , j , k ∗ j ∗ ( m − j − k ) ( j > 0 a n d m − j − k > 0 ) f_{i,j,k+1}+=f_{i-1,j,k}*j*(m-j-k)(j>0\ and\ m-j-k>0) fi,j,k+1​+=fi−1,j,k​∗j∗(m−j−k)(j>0 and m−j−k>0)


代码:

// luogu-judger-enable-o2
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define LL long long
#define LZX 9999973
using namespace std;
inline LL read() {LL d=0,f=1;char s=getchar();while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}return d*f;
}
LL f[105][105][105];
LL C(LL x) {return x*(x-1)/2;}
int main()
{LL n=read(),m=read();f[0][0][0]=1;for(LL i=0;i<n;i++)for(LL j=0;j<=m;j++)for(LL k=0;k+j<=m;k++){(f[i+1][j][k]+=f[i][j][k])%=LZX;if(m-j-k) (f[i+1][j+1][k]+=f[i][j][k]*(m-j-k))%=LZX;if(j) (f[i+1][j-1][k+1]+=f[i][j][k]*j)%=LZX;if(m-j-k&&j) (f[i+1][j][k+1]+=f[i][j][k]*j*(m-j-k))%=LZX;if(m-j-k>1) (f[i+1][j+2][k]+=f[i][j][k]*C(m-j-k))%=LZX;if(j>1) (f[i+1][j-2][k+2]+=f[i][j][k]*C(j))%=LZX;}LL ans=0;for(LL i=0;i<=m;i++)for(LL j=0;j+i<=m;j++)(ans+=f[n][i][j])%=LZX;cout<<ans%LZX;return 0;
}

洛谷 P2051 [AHOI2009]中国象棋【dp】相关推荐

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

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

  2. 洛谷 - P2051 [AHOI2009]中国象棋(计数dp)

    题目链接:点击查看 题目大意:给出一个 n * m 的棋盘,可以在任意位置放置 "炮",问一共可以放置多少种可行的方案 题目分析:转换题意,就是问每一行.每一列至多有两个棋子的方案 ...

  3. 洛谷2051 [AHOI2009]中国象棋

    题目链接 题意概述:n行m列棋盘放若干个棋子每行每列最多两个求方案总数,答案对9999973取模. 可以比较容易看出这是个dp,设f[i][j][k]表示前i行j列放1个棋子k列放2个棋子的方案总数. ...

  4. P2051 [AHOI2009]中国象棋

    题目链接 题目大意: 给定n*m大小表格,让你摆放棋子,摆放的要求是同一行.同一列中的棋子数不超过两个,问一共可能有多少摆法. (不看别人的题解真不会开dp数组,太弱小了) dp数组开三位,表示已经处 ...

  5. BZOJ 1801 [Ahoi2009]中国象棋(线性动规)(洛谷P2051)

    题意:就是在n*m的格子中放"炮"(中国象棋中的棋子)问有多少种放法,使得没有任意的两个炮相互攻击 思路:我们很容易的得到一列或者一行中最多放下两个炮(我也只能得到这些了,满脑子状 ...

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

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

  7. LG_2051_[AHOI2009]中国象棋

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

  8. AHOI2009 中国象棋

    题目链接 题目描述 在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. (在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同 ...

  9. 洛谷 P1063 能量项链 区间dp

    洛谷 P1063 题意:在一串项链中,是环状的,第 i 颗珠子有两个能量a[i]和a[i+1],第i+1颗珠子有两个能量a[i+1]和a[i+2],可以合并两个珠子,得到a[i]*a[i+1]*a[i ...

  10. 【洛谷 P2051】 [AHOI2009]中国象棋(DP)

    题目链接 首先想到状压dp,但是\(n,m\)高达100,怎么压? 容易发现,每行每列最多两个象棋,否则就直接gg了. 一个巧妙的设置状态的方式是,只需要记录到当前行有多少列是放了1个炮和2个炮. 然 ...

最新文章

  1. 013_JDK的Collections类的sort方法的实现
  2. Java UDP Demo
  3. 【福利】IT学习视频免费送:思科/华为、Liunx、ORACLE、VMware等等
  4. Linux 系统上出现^H
  5. 一步步使用SAP云平台的WebIDE开发SAP UI5应用
  6. linux java usb 串口_2019-11-02 Linux下USB-串口的使用
  7. [转]让你赚大钱成富翁的4个投资习惯
  8. Final Michael Scofield
  9. 在Pivotal Web Service上发布Spring Boot应用
  10. oracle19c监听服务启动失败,Oracle19c安装(有失败成功记录)
  11. 怎样查找html概念,HTML一般概念_html
  12. android一格一格向上的进度条,如何 使用 ProgressBar 进度条
  13. [六省联考2017]相逢是问候(线段树+拓展欧拉定理)
  14. python计算iv值_Python计算IV值的示例讲解
  15. 三国志·魏书·牵招传
  16. 浙江大学翁恺C++自学笔记
  17. 3D Max一些基本认识
  18. C语言经典例题100道
  19. PXI-10024100KSps、24Bit数据采集模块
  20. libtool 的使用。

热门文章

  1. opcua到mysql_基于python的opc读写和导入MSSQL/MYSQL的KepOPC中间件
  2. 学习-Java多路分支之百分制成绩转换GPA成绩
  3. 统计软件与数据分析Lesson9----爬虫解析库Beautiful Soup
  4. SpringBoot之SpringBoot整合JdbcTemplate
  5. 铁路行车组织之放射形专用线取送车顺序问题(自行设计MATLB代码)
  6. 电脑显示没有被指定在上运行_电脑出现**.dll没有被指定在Windows上运行怎么办...
  7. 临朐教师招聘计算机题,2020山东教师招聘专业基础知识:信息技术-计算机网络基础习题...
  8. jsp 获取页面元素java,获取java元素
  9. Object.assign与深、浅拷贝
  10. wmo(wow map object) research