Luogu P2051「AHOI2009」中国象棋
看见第一眼觉得是状压 \(\text{DP}\)?观察数据范围发现不可做
那按照最常规思路设状态试试?
设状态为\(dp[i][j]\)表示\(i*j\)的棋盘的方案数
好像转移不了欸 要不再来一维?
\(dp[i][j][k]\)表示。。。 还是不行啊
要求的就是每行,每列都不能有三个及其以上的炮
所以一共就只有三种状态:没有,一个炮,两个炮
但是列与列之间交换位置是完全没有问题的
所以设状态为 \(dp[i][j][k]\) 做了 \(i\) 行,有 \(j\) 列放了一个炮,有 \(k\) 列放了两个炮
如果第 \(i\) 行不放,则有
\]
放一个,则上一个状态一定是\(dp[i-1][j-1][k]\) 或者是 \(dp[i-1][j+1][k-1]\),由简单组合数学可得
\]
放两个,那一定从 \(dp[i-1][j][k-1]\) 或者 \(dp[i-1][j-2][k]\) 或者 \(dp[i-1][j+2][k-2]\)转移而来
则有(自己推式子感觉真好)
dp[i][j][k]+={C}_{m-k-(j-2)}^{2} \cdot dp[i-1][j-2][k]\\
dp[i][j][k]+={C}_{j+2}^{2}*dp[i-1][j+2][k-2]\\
\]
然后就是处理边界问题了
估计要开 \(long\ long\)(狗头
贴代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll p=9999973;
const ll maxn=1e2+10;
ll n,m,dp[maxn][maxn][maxn];
ll C(ll num)
{
return num*(num-1)/2;
}
int main()
{
scanf("%lld%lld",&n,&m);
dp[0][0][0]=1;
for(int i=1;i<=n;++i)
for(int j=0;j<=m;++j)
for(int k=0;j+k<=m;++k)
{
if(i-1>=0) dp[i][j][k]+=dp[i-1][j][k];
if(k-1>=0) dp[i][j][k]+=(j+1)*dp[i-1][j+1][k-1];
if(j-1>=0) dp[i][j][k]+=(m-k-(j-1))*dp[i-1][j-1][k];
if(k-2>=0) dp[i][j][k]+=C(j+2)*dp[i-1][j+2][k-2];
if(k-1>=0) dp[i][j][k]+=(m-j-(k-1))*j*dp[i-1][j][k-1];
if(j-2>=0) dp[i][j][k]+=C(m-k-(j-2))*dp[i-1][j-2][k];
dp[i][j][k]%=p;
}
ll ans=0;
for(int i=0;i<=m;++i)
for(int j=0;i+j<=m;++j)
ans=(ans+dp[n][i][j])%p;
printf("%lld\n",(ans+p)%p);
return 0;
}
\(\text{End.}\)
Luogu P2051「AHOI2009」中国象棋的更多相关文章
- BZOJ 1801: [Ahoi2009]chess 中国象棋( dp )
dp(i, j, k)表示考虑了前i行, 放了0个炮的有j列, 放了1个炮的有k列. 时间复杂度O(NM^2) -------------------------------------------- ...
- 【BZOJ1801】【AHOI2009】中国象棋(动态规划)
[BZOJ1801][AHOI2009]中国象棋(动态规划) 题面 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个 ...
- BZOJ_1801_[Ahoi2009]chess 中国象棋_DP
BZOJ_1801_[Ahoi2009]chess 中国象棋_DP Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像 ...
- 【BZOJ1801】[Ahoi2009]chess 中国象棋 DP
[BZOJ1801][Ahoi2009]chess 中国象棋 Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮 ...
- BZOJ1801 Ahoi2009 chess 中国象棋 【DP+组合计数】*
BZOJ1801 Ahoi2009 chess 中国象棋 Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行 ...
- Bzoj 1081 [Ahoi2009] chess 中国象棋
bzoj 1081 [Ahoi2009] chess 中国象棋 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1801 状态比较难设,的确 ...
- BZOJ1801 [Ahoi2009]chess 中国象棋(DP, 计数)
题目链接 [Ahoi2009]chess 中国象棋 设$f[i][j][k]$为前i行,$j$列放了1个棋子,$k$列放了2个棋子的方案数 分6种情况讨论,依次状态转移. #include <b ...
- bzoj1801: [Ahoi2009]chess 中国象棋(DP)
1801: [Ahoi2009]chess 中国象棋 题目:传送门 题解: 表示自己的DP菜的抠脚 %题解... 定义f[i][j][k]表示前i行 仅有一个棋子的有j列 有两个棋子的有k个 的方案数 ...
- LOJ #2116 Luogu P3241「HNOI2015」开店
好久没写数据结构了 来补一发 果然写的时候思路极其混乱.... LOJ #2116 Luogu P3241 题意 $ Q$次询问,求树上点的颜色在$ [L,R]$中的所有点到询问点的距离 强制在线 询 ...
随机推荐
- Go语言网络通信---一个简单的UDP编程
Server端: package main import ( "fmt" "net" ) func main() { //创建udp地址 udpAddr, _ ...
- Python+Selenium学习笔记19 - 自动发送邮件
发送简单的邮件 用一个QQ邮箱发送到另一个QQ邮件. 首先设置QQ邮箱,邮箱设置 -> 账号 开启SMTP服务,点击开启按钮,按提示进行操作,需要1毛钱的短信费.开启后如下所示 1 # codi ...
- Sqlserver语句获取本周、上一周、本月数据
sql语句获取本周.上一周.本月数据 获取周数据 1 本周 2 select * from table1 where datediff(week,时间字段,getdate()) = 0 3 上周 4 ...
- 8, java数据结构和算法: 从阶乘来看递归的调用
直接上代码 public class RecursionDemo { //从阶乘看 递归的调用机制 public static void main(String[] args) { System.ou ...
- 基于SKLearn的SVM模型垃圾邮件分类——代码实现及优化
一. 前言 由于最近有一个邮件分类的工作需要完成,研究了一下基于SVM的垃圾邮件分类模型.参照这位作者的思路(https://blog.csdn.net/qq_40186809/article/det ...
- 使用 Hexo 搭建静态博客
目录 Hexo 简介 什么是 Hexo? Hexo 安装 Hexo 建站 Hexo 配置 Hexo 自定义主题 Hexo 写作 Hexo 服务器 Hexo 生成与发布 一键部署 Hexo 站点到 gi ...
- Django(67)drf搜索过滤和排序过滤
前言 当我们需要对后台的数据进行过滤的时候,drf有两种,搜索过滤和排序过滤. 搜索过滤:比如我们想返回sex=1的,那么我们就可以从所有数据中进行筛选 排序过滤:比如我们想对价格进行升序排列,就可以 ...
- 纯小白干货:Java import以及Java类的搜索路径
如果你希望使用Java包中的类,就必须先使用import语句导入.import语句与C语言中的 #include 有些类似,语法为:import package1[.package2-].classn ...
- 十亿级流量下,我与Redis时延小突刺的战斗史
一.背景 某一日收到上游调用方的反馈,提供的某一个Dubbo接口,每天在固定的时间点被短时间熔断,抛出的异常信息为提供方dubbo线程池被耗尽.当前dubbo接口日请求量18亿次,报错请求94W/天, ...
- csp-s模拟测试58「Divisors」·「Market」·「Dash Speed」
A. Divisors 大概平均下来每个数也就几千约数吧....,直接筛 B. Market 可以把时间离线下来, 考试没有想到将询问离线,用数组存算了算只能过200的点,拿了70 事实上背包后直 ...