luogu 2051 [AHOI2009]中国象棋


真是一道令人愉♂悦丧心并框的好题。。。

首先“没有一个炮可以攻击到另一个炮”有个充分条件就是没有三个炮在同一行或同一列。证明:显然。

所以每行/每列最多2个炮。

还有一个点就是任意交换行和列不会改变这个方案的可行性。

那么可以脑补摆完前i行之后就把所有列排个序,会有摆了1个的列,摆了2个的列和没摆的列。

如果是桶排,就记录一下每个有多少就行了。

所以需要3个桶。可以省掉一个,因为知道了总共m列。

那么设f[i][j][k]为摆完了前i行,且j列摆了1个炮,k列摆了2个炮,你摆放的总方案数,然后滚动一下第一维

然后很多种情况,有注释。

PS.要多取膜!!!被坑到了

// It is made by XZZ
#include<cstdio>
#include<cstring>
#include<algorithm>
#define Fname "cchess"
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
#define mod 9999973
il int gi(){
rg int x=0;rg bool flg=0;rg char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return flg?-x:x;
}
ll f[2][101][101];
il vd add(ll&a,ll b){a+=b;if(a>=mod)a-=mod;}
int main(){
#ifdef xzz
freopen(Fname".in","r",stdin);
freopen(Fname".out","w",stdout);
#endif
int n=gi(),m=gi(),now=1;
f[0][0][0]=1;
rg ll t;
rep(i,0,n-1){
now^=1;
memset(f[now^1],0,sizeof f[now^1]);
drep(j,m,0)drep(k,m-j,0)if(f[now][j][k]){
t=(f[now][j][k]%=mod);
//第i行
add(f[now^1][j][k],t);//不放
add(f[now^1][j+1][k],t*(m-j-k)%mod);//放一个 新占一列
if(j)add(f[now^1][j-1][k+1],t*j%mod);//放一个 与一列放了一个的放一起
if(m-j-k>1)add(f[now^1][j+2][k],t*(m-j-k)*(m-j-k-1)/2%mod);//放两个 新占两列
if(j&&m-j-k>0)add(f[now^1][j][k+1],t*(m-j-k)*j%mod);//放两个 一个新占一列 另一个与一列放了一个的放一起
if(j>1)add(f[now^1][j-2][k+2],t*j*(j-1)/2%mod);//放两个 都与一列放了一个的放一起
}
}
ll ans=0;
now^=1;
rep(i,0,m)rep(j,0,m-i)add(ans,f[now][i][j]);
printf("%lld\n",ans);
return 0;
}

luogu 2051 [AHOI2009]中国象棋的更多相关文章

  1. Luogu 2051[AHOI2009]中国象棋 - DP

    Description 在 $n * m$ 的格子上放若干个炮, 使得每个炮都不能攻击到其他炮 Solution 定义数组f[ i ][ j ][ k ] 表示到了第 i 行, 已经有2个炮的列数为 ...

  2. [Luogu P2051] [AHOI2009]中国象棋 (状压DP->网格DP)

    题面 传送门:https://www.luogu.org/problemnew/show/P2051 Solution 看到这题,我们不妨先看一下数据范围 30pt:n,m<=6 显然搜索,直接 ...

  3. Luogu P2051 [AHOI2009]中国象棋(dp)

    P2051 [AHOI2009]中国象棋 题面 题目描述 这次小可可想解决的难题和中国象棋有关,在一个 \(N\) 行 \(M\) 列的棋盘上,让你放若干个炮(可以是 \(0\) 个),使得没有一个炮 ...

  4. luogu P2051 [AHOI2009]中国象棋

    统计方案,果断 dp 注意到合法方案即为每一行,每一列的棋子数不超过2 设\(f_{i,j,k}\)表示放到第\(i\)行,有\(j\)列可以放2个,有\(k\)列可以放1个的方案 然后就随便讨论一下 ...

  5. 洛谷.2051.[AHOI2009]中国象棋(DP)

    题目链接 /* 每行每列不能超过2个棋子,求方案数 前面行对后面行的影响只有 放了0个.1个.2个 棋子的列数,与排列方式无关 所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子 ...

  6. BZOJ1801或洛谷2051 [AHOI2009]中国象棋

    BZOJ原题链接 洛谷原题链接 这题挺难想状态的,刚看题感觉是状压,但数据\(100\)显然不可能. 注意到每行每列只能放\(0\sim 2\)个棋子,所以我们可以将这个写入状态. 设\(f[i][j ...

  7. Luogu P2051[AHOI2009]中国象棋【dp】By cellur925

    题目传送门 题目大意:给定一个$n*m$的棋盘,求放三个“炮”使它们不共行也不共列的方案数.($n,m$$<=100$) 这题主要是转移比较困难,因为情况比较多,所以需要冷静大胆细心地进行分情况 ...

  8. 洛谷2051 [AHOI2009]中国象棋

    题目链接 题意概述:n行m列棋盘放若干个棋子每行每列最多两个求方案总数,答案对9999973取模. 可以比较容易看出这是个dp,设f[i][j][k]表示前i行j列放1个棋子k列放2个棋子的方案总数. ...

  9. 洛谷 P2051 [AHOI2009]中国象棋 解题报告

    P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...

随机推荐

  1. 哈希表和字典List和Ilist和array和arraylist的应用

    string x = string.Empty; string y = string.Empty;                Hashtable ht = new Hashtable();     ...

  2. QTP基本方法4------手动写入信息到测试结果报告中

    可以使用写代码的方式添加结果信息到测试结果报告中. 结构:reporter.ReportEvent result,object,details,path result:状态:4种状态:micPass. ...

  3. 修改ubuntu计算机名

    修改计算机名下: -$sudo gedit /etc/hostname -$sudo gedit /etc/hosts

  4. ASP.NET Core MVC中Controller的Action如何直接使用Response.Body的Stream流输出数据

    在ASP.NET Core MVC中,我们有时候需要在Controller的Action中直接输出数据到Response.Body这个Stream流中,例如如果我们要输出一个很大的文件到客户端浏览器让 ...

  5. 【Javascript-基础-getOwnPropertyNames】Object.getOwnPropertyNames() 获取对象自身可枚举属性

    可枚举属性和不可枚举属性 在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的.可枚举性决定了这个属性能否被for-in查找遍历到. 可枚举属性 e ...

  6. 记一次jvm异常排查及优化

    为方便自己查看,根据工作遇到的问题,转载并整理以下jvm优化内容 有次接到客服反馈,生产系统异常,无法访问.接到通知紧急上后台跟踪,查看了数据库死锁情况--正常,接着查看tomcat 内存溢出--正常 ...

  7. oracle json 解析函数

    CREATE OR REPLACE TYPE ty_tbl_str_split IS TABLE OF ty_row_str_split;CREATE OR REPLACE TYPE ty_row_s ...

  8. iOS之面试题:腾讯三次面试以及参考思路

    使用了第三方库, 有看他们是怎么实现的吗? 例:SD.YY.AFN.MJ等! <1>.SD为例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ...

  9. http 协议状态码

    1xx   信息类状态码 100 - Continue 初始的请求已经接受,客户应当继续发送请求的其余部分.(HTTP 1.1新) 101 - Switching Protocols 服务器将遵从客户 ...

  10. Difftime

    功 能:返回两个time_t型变量之间的时间间隔,即 计算两个时刻之间的时间差. 用 法: double difftime(time_t time2, time_t time1);