状压DP之中国象棋
题目
传送们
这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法。大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子。你也来和小可可一起锻炼一下思维吧!
输入格式
一行包含两个整数N,M,之间由一个空格隔开。
输出格式
总共的方案数,由于该值可能很大,只需给出方案数模9999973的结果。
输入输出样例
样例输入
1 3
样例输出
7
思路
定义dp[i][j][k]数组代表第i行中,有j列有一个棋子,有k列有两个棋子,我们从当前状态递推下一状态,有6种情况
- 不放棋子,\(dp[i+1][j][k]=(dp[i+1][j][k]+dp[i][j][k])%mod\);
- 在没有棋子的一列中放一个棋子,\(dp[i+1][j+1][k]=(dp[i+1][j+1][k]+dp[i][j][k]*(m-j-k))%mod\);
- 在没有棋子的两列中放棋子,\(dp[i+1][j+2][k]=(dp[i+1][j+2][k]+dp[i][j][k]*c(m-j-k))%mod\);(c函数为求\(C^2_n\))
- 在有一个棋子的一列中放棋子,\(dp[i+1][j-1][k+1]=(dp[i+1][j-1][k+1]+dp[i][j][k]*j)%mod\);
- 在有一个棋子的两列放棋子,\(dp[i+1][j-2][k+2]=(dp[i+1][j-2][k+2]+dp[i][j][k]*c(j))%mod\);
- 在有一个棋子的一列和没有棋子的一列放棋子,\(dp[i+1][j][k+1]=(dp[i+1][j][k+1]+dp[i][j][k]*(m-j-k)*(j))%mod\);
然后跑个二维求解即可
附上代码一份
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
const int mod=9999973;
ll dp[110][110][110];
inline int c(int x){
return x*(x-1)/2;
}
int main(){
scanf("%d%d",&n,&m);
dp[0][0][0]=1;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
for(int k=0;k+j<=m;k++){
if(dp[i][j][k]){
dp[i+1][j][k]=(dp[i+1][j][k]+dp[i][j][k])%mod;
if(m-j-k>=1)dp[i+1][j+1][k]=(dp[i+1][j+1][k]+dp[i][j][k]*(m-j-k))%mod;
if(m-j-k>=2)dp[i+1][j+2][k]=(dp[i+1][j+2][k]+dp[i][j][k]*c(m-j-k))%mod;
if(j>=1)dp[i+1][j-1][k+1]=(dp[i+1][j-1][k+1]+dp[i][j][k]*j)%mod;
if(j>=2)dp[i+1][j-2][k+2]=(dp[i+1][j-2][k+2]+dp[i][j][k]*c(j))%mod;
if(m-j-k>=1 && j>=1)dp[i+1][j][k+1]=(dp[i+1][j][k+1]+dp[i][j][k]*(m-j-k)*(j))%mod;
}
}
}
}
long long ans=0;
for(int i=0;i<=m;i++){
for(int j=0;j+i<=m;j++){
ans=(ans+dp[n][i][j])%mod;
}
}
printf("%lld",ans);
}
状压DP之中国象棋的更多相关文章
- 洛谷P2051 [AHOI2009] 中国象棋(状压dp)
题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...
- 状压dp(状态压缩&&dp结合)学习笔记(持续更新)
嗯,作为一只蒟蒻,今天再次学习了状压dp(学习借鉴的博客) 但是,依旧懵逼·································· 这篇学习笔记是我个人对于状压dp的理解,如果有什么不对的 ...
- 状压DP入门详解+题目推荐
在动态规划的题型中,一般叫什么DP就是怎么DP,状压DP也不例外 所谓状态压缩,一般是通过用01串表示状态,充分利用二进制数的特性,简化计算难度.举个例子,在棋盘上摆放棋子的题目中,我们可以用1表示当 ...
- 状压DP之LGTB 与序列
题目 思路 这道题竟然是状压DP,本人以为是数论,看都没看就去打下一题的暴力了,哭 \(A_i\)<=30,所以我们只需要考虑1-58个数,再往后选的话还不如选1更优,注意,1是可以重复选取的, ...
- 状压dp大总结1 [洛谷]
前言 状态压缩是一种\(dp\)里的暴力,但是非常优秀,状态的转移,方程的转移和定义都是状压\(dp\)的难点,本人在次总结状压dp的几个题型和例题,便于自己以后理解分析状态和定义方式 状态压缩动态规 ...
- BZOJ 2064: 分裂( 状压dp )
n1+n2次一定可以满足..然后假如之前土地集合S1的子集subs1和之后土地集合S2的子集subs2相等的话...那么就少了2个+操作...所以最后答案就是n1+n2-少掉的最多操作数, 由状压dp ...
- 【BZOJ2064】分裂 状压DP
[BZOJ2064]分裂 Description 背景:和久必分,分久必和...题目描述:中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力.同时经常搞OI的他把这个变成了一个 ...
- BZOJ_2064_分裂_状压DP
BZOJ_2064_分裂_状压DP Description 背景: 和久必分,分久必和... 题目描述: 中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力. 同时经常搞OI的 ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
随机推荐
- java实现第五届蓝桥杯猜年龄
猜年龄 题目描述 小明带两个妹妹参加元宵灯会.别人问她们多大了,她们调皮地说:"我们俩的年龄之积是年龄之和的6倍".小明又补充说:"她们可不是双胞胎,年龄差肯定也不超过8 ...
- 教科书级讲解,秒懂最详细Java的注解
所有知识体系文章,GitHub已收录,欢迎Star!再次感谢,愿你早日进入大厂! GitHub地址: https://github.com/Ziphtracks/JavaLearningmanual ...
- .NET Core技术研究系列-索引篇
随着.NET Core相关技术研究的深入,现在将这一系列的文章,整理到一个索引页中,方便大家翻阅查找,同时,后续也会不断补充进来. .NET Core技术研究-WebApi迁移ASP.NET Core ...
- java作品集:企业信息门户webtap
作品背景 随着企业应用的软件越来越多,并且信息软件基本以B/S为主了,很多时候各种软件的地址,让大家记的头昏脑胀,并且一堆密码要记,而且大部分系统之间无法互通,虽然市面上有各种集成方案,但无法做到简单 ...
- InnoDB存储引擎的事务
事务的任务是保证一系列更新语句的原子性,锁的任务是解决并发访问可能导致的数据不一致问题.如果事务与事务之间存在并发操作,此时可以通过隔离级别实现事务的隔离性,从而实现数据的并发访问. 1 原子性(At ...
- 00-01.Kali Linux 2020.1修改root用户密码
安装Kali Linux 2020.1系统后,需要使用root用户权限安装软件. 由于VMWare版本的root用户默认密码未知,所以需要在单用户模式下重新设置root用户密码.操作步骤如下: 启动K ...
- 3、react-props/state
1.react中属性props和状态state 属性--静态得,所以在初始化得时候使用得是static进行初始化得,正常情况下属性不改 状态--动态得,它得值是可以发生改变得,react中的组件更新( ...
- <WP8开发学习笔记>获取手机的常用型号(如Lumia920,而非RM-822)
之前WP7时代可以用API获得WP手机的型号如lumia510,但是到了WP8后用APi只能获得硬件版本号了如RM-822,这种型号可以让我们更详细的了解具体的硬件版本,比如国行和港行,设备版本号不一 ...
- Linux系统命令详解
目录 1. su 1.1. su命令中passwd的自动输入 2. sshpass 3. locate/mlocate 4. top/htop 5. lftp 6. kill/killall 1. s ...
- drf之框架基础
(一)drf基础 全称:django-rest framework 接口:什么是接口.restful接口规范(协议) CBV(基于FBV的基础上形成).CBV生命周期源码----基于restful规范 ...