象棋,给你棋盘大小,然后放炮(炮的数量不限),不能让炮打到其他的炮,问方案数;

数据n,m<=200;

状态压缩似乎能做,但是我不会;

因为只要状态数,所以不必纠结每种状态的具体情况;

可以想出每行每列最多放两个棋子(我想到了吗?);

所以(为什么啊) 设计f[i][j][k]

表示DP到第i行,一列只有一个棋子的有j个,一列只有两个棋子的有k个;

清晰(模糊)转移方法

好,我们终于来到了第i行,加油;

这位OIer并不打算把棋子放在这一行,用f[i][j][k]直接继承f[i-1][j][k]的方案数;

然而(zhu)队友并不想就这样进入下一行,他要放棋子了!

请大家睁大眼睛,他在纠结

因为他最多只能放两个棋子,每一个棋子的位置都影响着当前的方案数;

他现在想放一个棋子,

两种选择:一,放在一列没有棋子的位置上,这样f[i][j][k]+=f[i][j-1][k]*(m-j+1-k)(乘法法则,有j-1个位置可以选)

二,放在一列只有一个棋子的位置上,这样f[i][j][k]+=f[i-1][j+1][k-1]*(j+1);

放两个棋子

(这个zhu队友想到现在头都大了,但是他离胜利不远了)

一,两个都放在没有棋子的一列,f[i][j][k]+=f[i-1][j-2][k]*(C(m-j-k+2))  (组合数,剩下的列中选两个位置,下面有代码)、

二,两个都放在有一个棋子的列上,f[i][j][k]+=f[i-1][j+2][k-2]*((j+2)*(j+1)/2)  (组合数公式)  (要时常记得,j+k<=m,如果放在j上,k会增加,j会减小)

三,一个放在没有棋子的列上,一个放在有一个棋子的列上,f[i][j][k]+=f[i-1][j][k-1]*j*(m-j-k+1) (j个位置有一个,但是一个放在这列j-1,另一个令j+1)

(队友阵亡,因为他没有判断边界);

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mo=;
const int maxn=;
ll f[maxn][maxn][maxn];
int n,m;
ll C(ll x)
{
return (x*(x-)/);
}
ll ans;
int main()
{
scanf("%d%d",&n,&m);
f[][][]=;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
for(int k=;k<=m-j;k++)
{
f[i][j][k]=f[i-][j][k];
if(k>=) f[i][j][k]+=f[i-][j+][k-]*(j+);
if(j>=) f[i][j][k]+=f[i-][j-][k]*(m-j-k+);
if(k>=) f[i][j][k]+=f[i-][j+][k-]*((j+)*(j+)/);
if(k>=) f[i][j][k]+=f[i-][j][k-]*j*(m-j-k+);
if(j>=) f[i][j][k]+=f[i-][j-][k]*C(m-j-k+);
f[i][j][k]%=mo;
}
}
}
for(int i=;i<=m;i++)
{
for(int j=;j<=m-i;j++)
{
ans+=f[n][i][j];
ans%=mo;
}
}
printf("%lld",ans);
return ;
}

P2051 [AHOI2009]中国象棋——DP(我是谁,我在哪,为什么)的更多相关文章

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

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

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

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

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

    题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...

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

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

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

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

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

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

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

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

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

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

  9. P2051 [AHOI2009]中国象棋

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

随机推荐

  1. poj 2406 求最短重复字串

    题解: KMP中next数组的巧妙运用.在这里我们假设这个字符串的长度是len,那么如果len可以被len-next[len]整除的话,我们就可以说len-next[len]就是那个最短子串的长度为什 ...

  2. (二十五)JSP九大内置对象(转)

    --转载自孤傲苍狼博客 一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质 ...

  3. WebSocket协议探究(一)

    一 复习和目标 1 复习 上一节使用wireshark抓包分析了WebSocket流量 包含连接的建立:HTTP协议升级WebSocket协议 使用建立完成的WebSocket协议发送数据 2 目标 ...

  4. Form key length limit 2048 exceeded ,提交数据时,数据的键过长 或者是上传文件过大

    在ASP.NET Core MVC中,文件的key 默认最大为2048,文件上传的最大上传文件默认为20MB,如果我们想上传一些比较大的文件,就不知道怎么去设置了,没有了Web.Config我们应该如 ...

  5. shell脚本使用记录

    一些比较功能需求比较简单的可以考虑使用shell脚本来写,这样可以方便快捷稳定 1. 读取文件值,根据文件值1 或 0 来开启和关闭某些程序 a.  while : do done 是无限循环. b. ...

  6. java小工具:通过URL连接爬取资源(图片)

    java语言编写一个简单爬取网站图片工具,实现简单: 通过 java.net.HttpURLConnection 获取一个URL连接 HttpURLConnection 连接成功返回一个java.io ...

  7. mongodb备份每一天的数据

    需求:把mongodb里面存储6个月的数据备份到本地,一天天的来备份,方便对备份管理.然后mongo保留一周的数据(优化查询速度,可以用mongo的ttl来实现,但是我的业务场景不太适合用ttl索引) ...

  8. Linux命令——diff、patch

    简介 diff以行为单位比较不同ASCII文件差异,可以输出一组指令,用于指导如何更改一个文件使其与第二个文件相同.diff在软件开发时多用于比较新旧版本代码,和patch连用可以将文件间区别做成补丁 ...

  9. [Mac][Python][Virtualenv]安装配置和使用

    安装帮助文档安装VirtualEnv报错如下 tekiMacBook-Air:workspaces hbai$ source /usr/local/bin/virtualenvwrapper.sh / ...

  10. RT-Thread--简介

    RT-Thread 概述 RT-Thread,全称是 Real Time-Thread,它是一个嵌入式实时多线程操作系统,基本属性之一是支持多任务,允许多个任务同时运行,但并不是真正的同时运行,而是宏 ...