题面

传送门:https://www.luogu.org/problemnew/show/P2051


Solution

看到这题,我们不妨先看一下数据范围

30pt:n,m<=6

显然搜索,直接爆搜水过

复杂度O(n^m(吧))

50pt: n<=100,m<=8

是状压/网络流的复杂度

当然,这题显然是状压

由题可以得出一个很显然但很重要的废话:每行每列只能放0~2个棋子

因此,我们可以考虑写一个3进制的状压DP

设f[i][j]表示第 i 行,每一列的具体情况以三进制的表达形式存在j里 的方案数

转移也很显然

分类转移一下

当前这一行放了0个棋子 f[i][j]+=f[i-1][j]

当前这一行放了1个棋子, 枚举一下有可能放的位置k f[i][j]+=xigema f[i-1][k]

当前这一行放了2个棋子 ,枚举一下那两个有可能放的位置,最后表达成k f[i][j]+=xigema f[i-1][k]

初始化f[0][0]=1,最后答案为 xigema f[n][i]

复杂度O(n*(3^m))

100pt:n,m<=100

其实之前50分做法离正解已经很接近了

再仔细思考(手玩)一下,就会发现答案与每一列棋子摆放位置无关

也就是说我们根本就没必要具体记录每一列的具体情况,只需要记录有多少列放了1个棋,有多少列放了2个棋

设f[i][j][k]表示第i行时有j列放了1个棋,有k列放了2个棋

然后转移和上面基本上没什么区别,具体请看代码

初始化f[0][0][0]=1.答案为 xigema f[n][i][j]

复杂度O(n*m*m)

Code

//Luogu P2051 [AHOI2009]中国象棋
//May,8th,2018
//状压转网格DP
#include<iostream>
#include<cstdio>
using namespace std;
long long read()
{
long long x=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int N=100+10;
const int poi=9999973;
long long f[N][N][N];
int n,m;
int main()
{
n=read(),m=read(); f[0][0][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
{
int MAX_K=m-j;
for(int k=0;k<=MAX_K;k++)
{
f[i][j][k]+=f[i-1][j][k];//放0个棋子
if(j>=1) f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k]*(m-k-j+1))%poi;//放1个棋子,且放在原本为0的列
if(k>=1) f[i][j][k]=(f[i][j][k]+f[i-1][j+1][k-1]*(j+1))%poi;//放1个棋子,且放在原本为1的列
if(j>=2) f[i][j][k]=(f[i][j][k]+f[i-1][j-2][k]*(((m-j-k+1)*(m-j-k+2))/2))%poi;//放2个棋子,且都放在原本为0的列
if(j>=1 and k>=1) f[i][j][k]=(f[i][j][k]+f[i-1][j][k-1]*(j*(m-j-k+1)))%poi;//放2个棋子,一个放在0,一个放在1
if(k>=2) f[i][j][k]=(f[i][j][k]+f[i-1][j+2][k-2]*(((j+1)*(j+2))/2))%poi;//放2个棋子,都放在原本为1的列
}
} long long ans=0;
for(int i=0;i<=m;i++)
{
int MAX_J=m-i;
for(int j=0;j<=MAX_J;j++)
ans=(ans+f[n][i][j])%poi;
}
printf("%lld",ans);
return 0;
}

正解(C++)

[Luogu P2051] [AHOI2009]中国象棋 (状压DP->网格DP)的更多相关文章

  1. 洛谷P2051 [AHOI2009] 中国象棋(状压dp)

    题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...

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

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

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

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

  4. luogu P2051 [AHOI2009]中国象棋

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

  5. 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP

    P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...

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

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

  7. luogu 2051 [AHOI2009]中国象棋

    luogu 2051 [AHOI2009]中国象棋 真是一道令人愉♂悦丧心并框的好题... 首先"没有一个炮可以攻击到另一个炮"有个充分条件就是没有三个炮在同一行或同一列.证明:显 ...

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

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

  9. [P2051 [AHOI2009]中国象棋] DP

    https://www.luogu.org/problemnew/show/P2051 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一 ...

随机推荐

  1. 晚间测试3 B. 单(single)

    题目描述 单车联通大街小巷.这就是出题人没有写题目背景的原因. 对于一棵树,认为每条边长度为 \(1\),每个点有一个权值\(a[i]\).\(dis(u,v)\)为点\(u\)到\(v\)的最短路径 ...

  2. 排序算法:归并排序(Merge Sort)

    归并排序 归并排序采用了分治策略(divide-and-conquer),就是将原问题分解为一些规模较小的相似子问题,然后递归解决这些子问题,最后合并其结果作为原问题的解. 归并排序将排序数组A[1. ...

  3. 030 01 Android 零基础入门 01 Java基础语法 03 Java运算符 10 条件运算符

    030 01 Android 零基础入门 01 Java基础语法 03 Java运算符 10 条件运算符 本文知识点:Java中的条件运算符 条件运算符是Java当中唯一一个三目运算符 什么是三目运算 ...

  4. 008 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 02 Java 中的关键字

    008 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 02 Java 中的关键字 关键字 关键字就是一些有特殊意义的词 之前学习的程序中涉及到的关键字 Java中 ...

  5. Cadence OrCAD如何查看整页原理图中的元件的属性

    转载: 1.选中DSN文件右键"Edit Object Properties ".在这里插入图片描述2.单击选择"Pivot"按钮. 3.找到Part refe ...

  6. [POI2009]ARC-Architects

    [POI2009]ARC-Architects 题意: 给定一个序列,从中挑选k个数,满足下标单调递增,并且字典序最小: 思路: 由于字典序最小,所以考虑贪心,即前面的数尽可能大,所以用单调队列维护最 ...

  7. CSS中居中的完全指南(中英对照翻译)

    翻译自:https://css-tricks.com/centering-css-complete-guide/ Centering things in CSS is the poster child ...

  8. 多测师讲解自动化测试 _RF关键字001_( 中)_高级讲师肖sir

    1.关键字如下 1.1Get Text 1.2Get Value 2.#上下滑动(滚动条) Open Browser http://www.jd.com gc Maximize Browser Win ...

  9. Oracle使用技巧

    Edit/Undo Ctrl+ZEdit/Redo Shift+Ctrl+ZEdit/PL/SQL Beautifier Ctrl+W (自定义) Shift+Home 选择光标位置到行首 Shift ...

  10. 程序员的“三十而已”,你都30岁了,不会还在XXX吧?

    一部<三十而已>火了 太太们的包包鄙视链出圈了 有人的地方就有江湖 是的,程序员入圈是容易的 不需要4万的LV,更不需要限量版的爱马仕 只需要一件耐躁的格子衫 然而,程序员的30岁, 却说 ...