洛谷 P2051 [AHOI2009]中国象棋 解题报告
P2051 [AHOI2009]中国象棋
题目描述
这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法。大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子。你也来和小可可一起锻炼一下思维吧!
输入输出格式
输入格式:
一行包含两个整数N,M,之间由一个空格隔开。
输出格式:
总共的方案数,由于该值可能很大,只需给出方案数模9999973的结果。
说明
样例说明
除了3个格子里都塞满了炮以外,其它方案都是可行的,所以一共有222-1=7种方案。
数据范围
100%的数据中N和M均不超过100
50%的数据中N和M至少有一个数不超过8
30%的数据中N和M均不超过6
一开始想打状压,但最后没时间了(校内开的考试)没打完,据说有50分。
对应状压的话,我们用两位来存储第i行是当前列已经存在几个炮。
分析一下发现,其实我们并不关注炮到底在哪里,只关心这一列有多少个(我感觉跟SDOI2010 地精部落有那么一点点的共同之处)
有时候,我们描述一个状态时,只关心其中某些的数量,而并不关系它的具体位置,转而用数学方法计算
用\(dp[i][j][k]\)代表目前到前i行 所有列 0放j个(即有\(j\)列还没放炮) 1放k(有\(k\)列已经放了一个炮)个的方案数
转移方程在代码里。
Code:
#include <cstdio>
#define ll long long
const int N=104;
const int mod=9999973;
ll n,m,dp[N][N][N],ans=0;
//dp[i][j][k]代表前i行 所有列 0放j个 1放k个的方案数
int main()
{
scanf("%lld%lld",&n,&m);
dp[0][m][0]=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][j][k]=(dp[i][j][k]+dp[i-1][j][k])%mod;//这排啥也不放
if(k) dp[i][j][k]=(dp[i][j][k]+dp[i-1][j+1][k-1]*(j+1))%mod;//一个0放1
dp[i][j][k]=(dp[i][j][k]+dp[i-1][j][k+1]*(k+1))%mod;//一个1放2
if(k>1) dp[i][j][k]=(dp[i][j][k]+(j+2)*(j+1)/2*dp[i-1][j+2][k-2])%mod;//双0放1
dp[i][j][k]=(dp[i][j][k]+(k+2)*(k+1)/2*dp[i-1][j][k+2])%mod;//双1放2
dp[i][j][k]=(dp[i][j][k]+dp[i-1][j+1][k]*(j+1)*k)%mod;//0,1各1
}
for(int i=0;i<=m;i++)
for(int j=0;j<=m-i;j++)
ans=(ans+dp[n][i][j])%mod;
printf("%lld\n",ans);
return 0;
}
2018.6.19
洛谷 P2051 [AHOI2009]中国象棋 解题报告的更多相关文章
- 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP
P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...
- [洛谷P2051] [AHOI2009]中国象棋
洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...
- 洛谷 P2051 [AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- 洛谷P2051 [AHOI2009]中国象棋(dp)
题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...
- 洛谷P2051 [AHOI2009] 中国象棋(状压dp)
题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...
- BZOJ1801或洛谷2051 [AHOI2009]中国象棋
BZOJ原题链接 洛谷原题链接 这题挺难想状态的,刚看题感觉是状压,但数据\(100\)显然不可能. 注意到每行每列只能放\(0\sim 2\)个棋子,所以我们可以将这个写入状态. 设\(f[i][j ...
- 洛谷 P4127 [AHOI2009]同类分布 解题报告
P4127 [AHOI2009]同类分布 题目描述 给出两个数\(a,b\),求出\([a,b]\)中各位数字之和能整除原数的数的个数. 说明 对于所有的数据,\(1 ≤ a ≤ b ≤ 10^{18 ...
- 洛谷.2051.[AHOI2009]中国象棋(DP)
题目链接 /* 每行每列不能超过2个棋子,求方案数 前面行对后面行的影响只有 放了0个.1个.2个 棋子的列数,与排列方式无关 所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子 ...
- 洛谷2051 [AHOI2009]中国象棋
题目链接 题意概述:n行m列棋盘放若干个棋子每行每列最多两个求方案总数,答案对9999973取模. 可以比较容易看出这是个dp,设f[i][j][k]表示前i行j列放1个棋子k列放2个棋子的方案总数. ...
随机推荐
- BZOJ4999: This Problem Is Too Simple!树链剖分+动态开点线段树
题目大意:将某个节点的颜色变为x,查询i,j路径上多少个颜色为x的点... 其实最开始一看就是主席树+树状数组+DFS序...但是过不去...MLE+TLE BY FCWWW 其实树剖裸的一批...只 ...
- [SDOI2009]HH的项链 BZOJ1878
分析: 听说是莫队裸题,很显然,我并不喜欢莫队. 我们可以考虑将询问离线,以右端点排序,之后从1枚举到n,依次树状数组中修改i和last[i],之后当i==询问的右节点时,find一下答案就可以了. ...
- Java转python第一天
1.python xx.py 2.字符串可以与数字相乘 str = "abc" msg = str*3 print(msg) # 结果:abcabcabc 3.换行用三个单引号 ' ...
- # 2017-2018-2 20155319 『网络对抗技术』Exp8:Web基础
2017-2018-2 20155319 『网络对抗技术』Exp8:Web基础 一.原理与实践说明 1.实践具体要求 (1).Web前端HTML(0.5分) 能正常安装.启停Apache.理解HTML ...
- 20155339平措卓玛 Exp2 后门原理与实践
20155339平措卓玛Exp2 后门原理与实践 基础问题 (1)例举你能想到的一个后门进入到你系统中的可能方式? 答:下载并安装某个程序,这个程序可以正常的并且完整的为我们提供服务,但是在开发改程序 ...
- CM005-逆向分析过程(上篇)
前言 005,都说比较变态,很多人给放过去了,但是我还是决定上了它,既然变态就分两篇,上篇先实际说流程,到底应该怎么上它,下篇会告诉逆向分析的过程和方法 准备 [环境和工具] win7/xp虚拟机环境 ...
- First day for introducing me
""" This is first python3 script code for lyp in Bokeyuan __author__="lyp" ...
- Unity日记—对象缓存池
最近都在忙别的事了,今天忙里偷闲了解了一下对象池是啥玩意,简单记录一下. 还是个正在学习的萌新,如果写的不好请见谅. 1.对象池是啥 在了解对象池之后,我才意识到以前写的代码有多么蠢,当场景中有一些重 ...
- React笔记-事件分发
事件分发 之前讲述了事件如何绑定在document上,那么具体事件触发的时候是如何分发到具体的监听者呢?我们接着上次注册的事件代理看.当我点击update counter按钮时,触发注册的click事 ...
- [翻译]:Cinemachine 官方文档(0)
目录 Overview : Installation and Getting Started :安装并开始 User Guide :用户指南 What is Cinemachine? : 什么是Cin ...