洛谷P2051 中国象棋【dp】
题目:https://www.luogu.org/problemnew/show/P2051
题意:n*m的格子里放炮,使他们不能互相攻击。
如果两个炮在同一行同一列并且中间还有一个棋子的话就可以攻击。问有多少种放炮的方案。
思路:首先根据规则,可以推出任意的行和列中炮的个数都不能超过2个。
可以尝试用递推。$dp[i][j][k]$表示处理到第$i$行,只有一个炮的列有$j$个,有两个炮的列有$k$个时的方案数。
当$i-1$行处理完了处理$i$的时候,可以放0,1,2个炮。
所以$dp[i][j][k] = dp[i-1][j][k] + dp[i-1][j-1][k] * (m - j - k + 1) + dp[i - 1][j + 1][k - 1] * (j + 1) + dp[i - 1][j - 2][k] * (m - j - k + 2)(m - j - k + 1) + dp[i - 1][j + 2][k - 2] * (j + 2)(j + 1)/2 + dp[i- 1][j][k - 1] * j(m - j - k + 1)$【每次像这种到老是会搞乱到底是谁推出谁的关系】
注意中间过程可能会爆int,所以直接用LL做吧。
#include<cstdio>
#include<cstdlib>
#include<map>
#include<set>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stack>
#include<queue>
#include<iostream> #define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef pair<int, int> pr; int n, m;
const int maxn = ;
const LL mod = ;
LL dp[maxn][maxn][maxn]; int main()
{
scanf("%d%d", &n, &m);
dp[][][] = ;
for(int i = ; i <= n; i++){
for(int j = ; j <= m; j++){
for(int k = ; j + k <= m; k++){
dp[i][j][k] = (dp[i][j][k] + dp[i - ][j][k]) % mod;
if(j >= )dp[i][j][k] = (dp[i][j][k] + dp[i - ][j - ][k] * (m - j - k + )) % mod;
if(k >= && j + <= m)dp[i][j][k] = (dp[i][j][k] + dp[i - ][j + ][k - ] * (j + )) % mod;
if(j >= )dp[i][j][k] = (dp[i][j][k] + dp[i - ][j - ][k] * ((m - j - k + ) * (m - j - k + ) / )) % mod;
if(k >= && j + <= m)dp[i][j][k] = (dp[i][j][k] + dp[i - ][j + ][k - ] * ((j + ) * (j + ) / )) % mod;
if(k >= )dp[i][j][k] = (dp[i][j][k] + dp[i - ][j][k - ] * j * (m - j - k + )) % mod;
}
}
} LL ans = ;
for(int j = ; j <= m; j++){
for(int k = ; j + k <= m; k++){
ans = (ans + dp[n][j][k]) % mod;
}
}
printf("%lld\n", ans);
return ;
}
洛谷P2051 中国象棋【dp】的更多相关文章
- 洛谷P2051 中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- 洛谷 - P2051 - 中国象棋 - 简单dp
https://www.luogu.org/problemnew/show/P2051 一点都不简单的简单dp. 还是从旧行转移到新行,而不是考虑新行从哪些旧行转移吧. #include<bit ...
- 洛谷P2051 中国象棋(dp)
题目链接:传送门 题目大意: 在N行M列的棋盘中放象棋中的“炮”,问要使得“炮”两两互不伤害,有多少种放法. 1 ≤ n,m ≤ 100,答案对9999973取模. 思路: 按行更新答案.每行炮可以放 ...
- 洛谷 [P2051] 中国象棋
DP orz__stdcall 首先要想出来,每行最多只能放两个棋子,这是显然的 于是决策就是一行一行地处理 30分的做法就是裸的枚举,暴搜,枚举这一行放哪里,放几个 然后想到了压位dp,按3进制表示 ...
- 洛谷 P2051 中国象棋 题解
题面 状态可能不太好想,设f[i][j][k]表示前i行其中有j行是放一个炮,有k行是放两个炮的合法方案数: 那么: f[i+1][j][k]+=f[i][j][k] 在这一行不放任何棋子: ...
- P2051 中国象棋
P2051 中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中 ...
- 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP
P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...
- [洛谷P2051] [AHOI2009]中国象棋
洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...
- 洛谷 P2051 [AHOI2009]中国象棋 解题报告
P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...
随机推荐
- hdoj4099(字典树+高精度)
题目链接:https://vjudge.net/problem/HDU-4099 题意:给T组询问,每个询问为一个字符串(长度<=40),求以该字符串为开始的fibonacci数列的第一个元素的 ...
- 6.66 分钟,一文Python爬虫解疑大全教入门!
我收集了大家关注爬虫最关心的 16 个问题,这里我再整理下分享给大家,并一一解答. 1. 现在爬虫好找工作吗? 如果是一年前我可能会说爬虫的工作还是挺好找的,但现在已经不好找了,一市场饱和了,二是爬 ...
- nginx 二级目录高级写法
nginx二级目录高级配置: location ~ .*\.(html)$ { expires 1m; error_page 404 = /test/index.html; access_log /d ...
- mysql数据库语言分类
MySQL的sql语言分类DML.DQL.DDL.DCL. MySQL的sql语言分类DML.DQL.DDL.DCL. SQL语言一共分为4大类:数据定义语言DDL,数据操纵语言DML,数据查询语 ...
- python 之 数据库(视图、触发器、事务、存储过程)
10.13 视图 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次用的直接使用即可 2.为什么要用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图 视图记录的增.删 ...
- python学习-58 configparse模块
configparse模块 1.生成文件 import configparser # 配置解析模块 config = configparser.ConfigParser() # config = { ...
- golang之结构体结构体嵌入和匿名成员
考虑一个二维的绘图程序,提供了一个各种图形的库,例如矩形.椭圆形.星形和轮形等几何形状.这里是其中两个的定义: type Circle struct { X, Y, Radius int } type ...
- 11 模块、模块的搜索顺序、__file__内置属性、__name__属性
模块的概念 一个python文件就是一个模块. 模块名同时也是一个标识符,需要符合标识符的命名规则. 在模块中定义的全局变量.函数.类 都是个外界提供的直接使用的工具. 模块就好比工具包,要想使用一个 ...
- jquery封装的方法
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- javascript序列化表单追加参数
js序列化表单后追加参数方式: 追加参数:token,status var data = $.param({"token":token, "status":st ...