题意:在棋盘上放一些炮使得它们不互相攻击。其实就是一行/一列最多放两个。

50分的数据中n,m至少有一个不超过8,比较直接的想法是对n/m中较小的一维做状态压缩,状态f[i][S1][S2]表示在前i行/列中,S1集合中的列/行放了1炮,S2集合中的列/行放了2炮。转移的时候,需要枚举第i行/列怎么放炮。这个时间复杂度好像炸天了….

仔细观察转移的过程,会发现S1和S2集合中的元素到底是谁其实无关紧要,我们只需要知道S1和S2的元素数目即可完成转移。所以可以把状态改成f[i][j][k]表示前i行有j列放了1炮,k列放了2炮的方案数,依然讨论第i行的方法,不过不需要逐个枚举方案。

因为闲得蛋疼把数组开成了两维,我的DP顺序比较奇怪…某个状态一定是从总炮数小于等于它的状态转移过来(等于的情况只有不放炮一种,写的时候不需要考虑,直接从之前继承下来),所以只要按照总炮数从大到小DP就行了。不过这题并没有卡内存,所以开成三维数组的话总是从i-1那一层转移过来,循环顺序怎样都没关系.

转移的时候,f[i][j][k]可以从f[i-1][j][k-1]转移过来,看起来是放一个炮的列数不变,放两个炮的列数+1,但不能理解成在一个空列上放两炮使得它变成有两炮的列,实际的过程是在一个空列放了一炮,在另一个之前有1炮的列上再放了1炮,因为在第i行每一列只能放一炮

我加了滚动数组之后864kb,404ms,bzoj上有人176kb就过了,而且跑得飞起,30ms.甚至还有0msAC的…不知道别人怎么做的,只能ym。

#include<cstdio>
const int maxn=,mod=;
int f[maxn][maxn];
int main(){
int n,m;scanf("%d%d",&n,&m);
f[][]=;
int lim=*m;
int ans=;
for(int i=;i<=n;++i){
for(int tot=lim;tot>=;--tot){//倒着枚举,类似于01背包的方法
for(int k=;k*<=tot;++k){
int j=tot-k*;
if(j>m)continue;
          //这一行放一炮
if(j!=){
f[j][k]+=(m-(k)-(j-))*1LL*f[j-][k]%mod;
} if(k!=){ f[j][k]+=(j+)*1LL*f[j+][k-]%mod; } //这一行放两炮
if(j>=){
f[j][k]+=(m-k-(j-))*1LL*(m-k-(j-))/2LL*f[j-][k]%mod;
}
if(k>=){
f[j][k]+=(j+)*(j+)/2LL*f[j+][k-]%mod;
}
if(k>=){
f[j][k]+=(m-j-k+)*1LL*(j)*f[j][k-]%mod;
}
f[j][k]%=mod;
if(i==n)ans=(ans+f[j][k])%mod;
}
}
}
printf("%d\n",ans);
return ;
}

bzoj1801[AHOI2009]CHESS中国象棋的更多相关文章

  1. BZOJ1801 Ahoi2009 chess 中国象棋 【DP+组合计数】*

    BZOJ1801 Ahoi2009 chess 中国象棋 Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行 ...

  2. BZOJ1801 [Ahoi2009]chess 中国象棋(DP, 计数)

    题目链接 [Ahoi2009]chess 中国象棋 设$f[i][j][k]$为前i行,$j$列放了1个棋子,$k$列放了2个棋子的方案数 分6种情况讨论,依次状态转移. #include <b ...

  3. bzoj1801: [Ahoi2009]chess 中国象棋(DP)

    1801: [Ahoi2009]chess 中国象棋 题目:传送门 题解: 表示自己的DP菜的抠脚 %题解... 定义f[i][j][k]表示前i行 仅有一个棋子的有j列 有两个棋子的有k个 的方案数 ...

  4. [luogu2051][bzoj1801][AHOI2009]chess中国象棋【动态规划】

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

  5. BZOJ1801 [Ahoi2009]chess 中国象棋 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1801 题意概括 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请 ...

  6. BZOJ1801:[Ahoi2009]chess 中国象棋

    Time Limit: 10 Sec  Memory Limit: 64 MB Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置 ...

  7. bzoj1801: [Ahoi2009]chess 中国象棋 dp

    题意:在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧. 题解:dp[i][j][k]表示到了第i行,有j列 ...

  8. BZOJ1801 [Ahoi2009]chess 中国象棋 【dp】

    题目 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧. 输入格式 一行包含两个整数N,M,中间用空格分开. ...

  9. 【BZOJ1801】[Ahoi2009]chess 中国象棋 DP

    [BZOJ1801][Ahoi2009]chess 中国象棋 Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮 ...

随机推荐

  1. JUnit4测试简介

    相比于自己写一个测试类,在里面调用调试方法,使用JUnit4进行测试有很多的优点,极大的提高了测试的速度.本文简单介绍如何使用myEclipse10使用JUnit4,方便日后回顾总结. myEclip ...

  2. 利用Canvas进行绘制XY坐标系

    首先来一发图 绘制XY的坐标主要是利用Canvas setLeft和setBottom功能(Canvas内置坐标的功能) 1.首先WPF中的坐标系都是从左到右,从上到下的 即左上角位置(0,0)点,所 ...

  3. Apache下开启SSI配置使html支持include包含

    写页面的同学通常会遇到这样的烦恼,就是页面上的 html 标签越来越多的时候,寻找指定的部分就会很困难,那么能不能像 javascript 一样写在不同的文件中引入呢?答案是有的,apache 能做到 ...

  4. Linux下网络流量实时监控工具

    Linux下网络流量实时监控工具大全 在工作中发现,经常因为业务的原因,需要即时了解某台服务器网卡的流量,虽然公司也部署了cacti软件,但cacti是五分钟统计的,没有即时性,并且有时候打开监控页面 ...

  5. 东大OJ-1040-Count-快速幂方法求解斐波那契-

    Many ACM team name may be very funny,such as "Complier_Error","VVVVV".Oh,wait fo ...

  6. hibernate 3.3.2GA版的下载

    网上马士兵老师采用的hibernate教程所使用的jar包便是hibernate 3.3.2GA,下载连接如下: http://download.csdn.net/detail/foreversile ...

  7. java 上传图片 并压缩图片大小

    Thumbnailator 是一个优秀的图片处理的Google开源Java类库.处理效果远比Java API的好.从API提供现有的图像文件和图像对象的类中简化了处理过程,两三行代码就能够从现有图片生 ...

  8. Oracle数据库下sde用户系统表开放权限sql语句

    --sde用户登陆执行以下语句 grant insert, update, delete on sde.table_registry to PUBLIC; grant insert, update, ...

  9. lucene-查询query->FuzzyQuery相近词语的搜索

    FuzzyQuery是一种模糊查询,它可以简单地识别两个相近的词语.下面以11.10为例进行详细介绍. package ch11; import org.apache.lucene.analysis. ...

  10. Android核心机制

    Android开篇 图解Android - Zygote, System Server 启动分析 图解Android - Binder 和 Service 图解Android - System Ser ...