洛谷 - P2051 - 中国象棋 - 简单dp
https://www.luogu.org/problemnew/show/P2051
一点都不简单的简单dp。
还是从旧行转移到新行,而不是考虑新行从哪些旧行转移吧。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
namespace combinatorics{
const ll MOD=9999973;
//1. 快速幂 x^n %mod
inline ll qpow(ll x,ll n,ll mod=MOD) {
ll res=1%mod;
while(n) {
if(n&1)
res=res*x%mod;
x=x*x%mod;
n>>=1;
}
return res;
}
//3. 乘法逆元 快速幂+费马小定理,要求p必须是质数 (依赖1. 快速幂)
inline ll inv_p(ll n,ll p=MOD) {
return qpow(n,p-2,p);
}
};
using namespace combinatorics;
//注意需要init(),必要时修改常量
ll dp[101][101][101]={};
//前i行中,j列放了1个,k列放了2个的方法数
int main(){
int n,m;
scanf("%d%d",&n,&m);
ll inv2=inv_p(2,MOD);
dp[1][0][0]=1;
//不放也是一种方法
dp[1][1][0]=m;
//只有1列放了1个
if(m>=2)
dp[1][2][0]=(ll)m*(m-1)%MOD*inv2%MOD;
//只有2列放了1个
for(int i=1;i<n;i++){
for(int j=0;j<=m;j++){
for(int k=0;k<=m-j;k++){
//这一行不放
dp[i+1][j][k]=(dp[i+1][j][k]+dp[i][j][k])%MOD;
int v=m-j-k;
//放一个在空列,有v种放法
if(v-1>=0&&j+1<=m)
dp[i+1][j+1][k]=(dp[i+1][j+1][k]+dp[i][j][k]*v)%MOD;
//放一个在原本有1个的列,有j种方法
if(j-1>=0&&k+1<=m)
dp[i+1][j-1][k+1]=(dp[i+1][j-1][k+1]+dp[i][j][k]*j)%MOD;
//放两个,两个都在空列
if(v-2>=0&&j+2<=m)
dp[i+1][j+2][k]=(dp[i+1][j+2][k]+dp[i][j][k]*(v)*(v-1)*inv2)%MOD;
//放两个,两个都在原本有1个的列
if(j-2>=0&&k+2<=m)
dp[i+1][j-2][k+2]=(dp[i+1][j-2][k+2]+dp[i][j][k]*(j)*(j-1)*inv2)%MOD;
//放两个,一个在空列,一个在原本有1个的列
if(v-1>=0&&k+1<=m)
dp[i+1][j][k+1]=(dp[i+1][j][k+1]+dp[i][j][k]*v*j)%MOD;
//printf("dp[%d][%d][%d]=%lld\n",i,j,k,dp[i%2][j][k]);
}
}
}
//puts("");
ll ans=0;
for(int j=0;j<=m;j++){
for(int k=0;k<=m-j;k++){
ans=(ans+dp[n][j][k])%MOD;
//printf("dp[%d][%d][%d]=%lld\n",n,j,k,dp[n%2][j][k]);
}
}
printf("%lld\n",ans);
}
洛谷 - P2051 - 中国象棋 - 简单dp的更多相关文章
- 洛谷P2051 中国象棋【dp】
题目:https://www.luogu.org/problemnew/show/P2051 题意:n*m的格子里放炮,使他们不能互相攻击. 如果两个炮在同一行同一列并且中间还有一个棋子的话就可以攻击 ...
- 洛谷P2051 中国象棋(dp)
题目链接:传送门 题目大意: 在N行M列的棋盘中放象棋中的“炮”,问要使得“炮”两两互不伤害,有多少种放法. 1 ≤ n,m ≤ 100,答案对9999973取模. 思路: 按行更新答案.每行炮可以放 ...
- 洛谷P2051 中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- 洛谷 [P2051] 中国象棋
DP orz__stdcall 首先要想出来,每行最多只能放两个棋子,这是显然的 于是决策就是一行一行地处理 30分的做法就是裸的枚举,暴搜,枚举这一行放哪里,放几个 然后想到了压位dp,按3进制表示 ...
- 洛谷 P2051 中国象棋 题解
题面 状态可能不太好想,设f[i][j][k]表示前i行其中有j行是放一个炮,有k行是放两个炮的合法方案数: 那么: f[i+1][j][k]+=f[i][j][k] 在这一行不放任何棋子: ...
- 洛谷P1130红牌(简单DP)
题目描述 某地临时居民想获得长期居住权就必须申请拿到红牌.获得红牌的过程是相当复杂 ,一共包括NNN个步骤.每一步骤都由政府的某个工作人员负责检查你所提交的材料是否符合条件.为了加快进程,每一步政府都 ...
- 洛谷 - P1002 - 过河卒 - 简单dp
https://www.luogu.org/problemnew/show/P1002 方程很好想,题目也很暴力.感谢题目提示数据会很大. #include<bits/stdc++.h> ...
- 【Luogu】P2051中国象棋(DP)
题目链接 去看STDCALL的题解吧 #include<cstdio> #include<cctype> #define mod 9999973 inline long lon ...
- P2051 中国象棋
P2051 中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中 ...
随机推荐
- vue 生命周期钩子
每个vue实例被创建时都会经历一系列初始化的过程,像是一个生命从无到有的过程,所以叫生命周期,而这个过程都有对应的不同阶段,也就对应了生命周期不同的钩子函数,这些生命周期函数,作为vue实例的属性使用 ...
- 三星note3 N900刷机包 4.4.2 ZSUDNE3 官方原汁原味 稳定流畅
ROM介绍 此ROM基于最新的4.4.2 ZSUDNE3 制作,加入一些必要功能,其它性能基本与官方无差距,各方面感觉都非常不错了.此ROM本人自用,所以制作风格有点个人倾向.不论什么建议或者问题欢迎 ...
- Java面向对象编程(一)
由于常常将Java和C++面向对象编程的原则搞乱,所以这次把相关要点分别总结一下,本文主要总结Java面向对象编程. 面向对象编程的三大特性是:继承性(inheritance), 多态性(polymo ...
- Pipeline(netty源码)
精进篇:netty源码死磕6 巧夺天工--Pipeline模式揭秘 1. 巧夺天工--Pipeline模式揭秘 1.1. Pipeline模式简介 管道的发名者叫,Malcolm Douglas M ...
- Hadoop实战-MapReduce之max、min、avg统计(六)
1.数据准备: Mike,35 Steven,40 Ken,28 Cindy,32 2.预期结果 Max 40 Min 28 Avg 33 3.MapReduce代码如下 import ja ...
- mybatis是什么?(二)
mybatis是什么? mybatis是一个持久层的框架,是apache下的顶级项目. mybatis托管到goolecode下,再后来托管到github下(https://github.com/my ...
- self = [super init]的解释
在Object-C中我们很多时候都会重写init方法.一般情况下我们都会这样写: -(instancetype)initWithDic:(NSDictionary *)dic{ if(self=[su ...
- 在dw中 <!----> 和 /**/ 的区别?
<!-- -->是HTML的注释标签,使用<和>是符合HTML标签语法规则的./* */是CSS和JS的注释标签.两种注释有各自的使用环境,并且不能相互替代.
- BestCoder Round #92 1001 Skip the Class —— 字典树 or map容器
题目链接:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=748&pid=1001 题解: 1.trie树 关 ...
- 信息发布员和频道管理员如何查看dedecms自定义表单内容
自定义表单的管理权限,超级管理员有,而频道管理员没有.在频道管理员的权限设置选项里,找不到自定义表单这一项.怎么办呢. 刚开始想修改权限设置选项,但觉得太麻烦.是否有偷懒取巧的办法? 在频道管理员的后 ...