luogu 3158 [CQOI2011]放棋子
时隔多日 我又来挑战这道dp。
几个月前给写自闭了。几个月后再来。
首先一个我们能列出来的状态 是以行为转移的 f[i]表示前i行...但是会发现此时列我们控制不了 且棋子的颜色,个数我们也要放到状态里。
这个dp是一个完成不了 或者说复杂度过高的dp。
必须得换一个状态 可以想到 由于每种颜色棋子独立 所以我们没有必要若干个颜色的棋子进行混合求方案。
可以一种一种颜色的棋子放。
所以有状态 f[i][j][k]表示前i种颜色的棋子占领了j行K列的方案数。
这样行和列的状态有了 我们只需要安排一下当前颜色怎么放。
当前颜色有a[i]个棋子。枚举一下 这么多棋子能占 l行 r列。
发现我们很难去形成用a[i]个棋子完美占领l行r列。但是若a[i]<l||a[i]<r方案数显然为0.
设S=空余的位置数 C(S,a[i])我们先强行安排位置。再减掉不合法的方案。
不合法方案=没有占领够l行+没有占领够r行-前两者的交集。
这里的容斥里面是一个类似于代表元容斥的东西。显然没够l行 说明最多<=l-1都是不合法的 对列同样如此。
最后两者不合法的交集要加回来即可。
不过这样容斥是错误的 原因是 我们的不合法方案中可能有状态是重复的如l-1行不合法我们外面还要乘一个C(l,l-1)*l-1行的不合法。
仔细观察 l-1行的不合法并不代表l-1行全部被占 所以外面再乘以l说明一些方案被重复计算了但是不这样做也不对 不合法的方案需要枚举出哪一行没有被占。
所以我们考虑一个新的容斥 这次我们不合法方案定义为 精确的占了wl,wr行 确保他们都被占了 这样就不会出现上述情况了。
但是wl,wr需要枚举 我们需要把所有不合法的都给减掉。这样是\(c\cdot n^3\cdot m^3\)发现这个东西显然可以预处理一下 所以复杂度降低一个nm.
这样总复杂度为\(sum \cdot n^2\cdot m^2\) 可以通过。我终于战胜了这道题目。
有的晕了。。
需要注意的是 开longlong (我以为一个地方不会爆然后爆了 千万不要以为!
对于预处理 我们只需要处理a[i]即可 我没想好 把1~mx都给处理了。
const int MAXN=31,maxn=2010;
int n,m,c,maxx,mx;
int a[MAXN],vis[maxn];
ll g[maxn][MAXN][MAXN];//表示i个棋子占了j行k列的方案数。
ll f[MAXN][MAXN][MAXN];//f[i][j][k]表示前i种颜色占了i行j列的方案数.
ll fac[maxn],inv[maxn],ans;
inline int ksm(ll b,int p)
{
ll cnt=1;
while(p)
{
if(p&1)cnt=cnt*b%mod;
b=b*b%mod;
p=p>>1;
}
return cnt;
}
inline void prepare()
{
fac[0]=1;
rep(1,maxx,i)fac[i]=fac[i-1]*i%mod;
inv[maxx]=ksm(fac[maxx],mod-2);
for(int i=maxx-1;i>=0;--i)inv[i]=inv[i+1]*(i+1)%mod;
}
inline ll C(int a,int b)
{
if(a<b)return 0;
return fac[a]*inv[b]%mod*inv[a-b]%mod;
}
int main()
{
//freopen("1.in","r",stdin);
get(n);get(m);get(c);
rep(1,c,i)get(a[i]),mx=max(mx,a[i]),vis[a[i]]=1;
maxx=n*m;prepare();
f[0][0][0]=1;g[0][0][0]=1;
rep(1,mx,i)
{
if(!vis[i])continue;
rep(1,n,j)rep(1,m,k)
{
if(i<j||i<k)continue;
rep(1,j,w1)rep(1,k,w2)
{
if(w1==j&&k==w2)g[i][j][k]=(g[i][j][k]+C(j*k,i))%mod;
else g[i][j][k]=(g[i][j][k]-C(j,w1)*C(k,w2)%mod*g[i][w1][w2]%mod)%mod;
}
}
}
rep(1,c,i)//前i种颜色
{
rep(0,n,j)rep(0,m,k)
{
if(!f[i-1][j][k])continue;
rep(1,n-j,l)rep(1,m-k,r)
{
if(a[i]<l||a[i]<r)continue;
f[i][j+l][k+r]=(f[i][j+l][k+r]+C(n-j,l)*C(m-k,r)%mod*f[i-1][j][k]%mod*g[a[i]][l][r]%mod)%mod;
}
}
}
rep(1,n,j)rep(1,m,k)ans=(ans+f[c][j][k])%mod;
printf("%lld\n",(ans+mod)%mod);
return 0;
}
luogu 3158 [CQOI2011]放棋子的更多相关文章
- BZOJ 3294: [Cqoi2011]放棋子
3294: [Cqoi2011]放棋子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 628 Solved: 238[Submit][Status] ...
- bzoj3294[Cqoi2011]放棋子 dp+组合+容斥
3294: [Cqoi2011]放棋子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 755 Solved: 294[Submit][Status] ...
- [CQOI2011]放棋子 (DP,数论)
[CQOI2011]放棋子 \(solution:\) 看到这道题我们首先就应该想到有可能是DP和数论,因为题目已经很有特性了(首先题面是放棋子)(然后这一题方案数很多要取模)(而且这一题的数据范围很 ...
- bzoj千题计划261:bzoj3294: [Cqoi2011]放棋子
http://www.lydsy.com/JudgeOnline/problem.php?id=3294 如果一个颜色的棋子放在了第i行第j列,那这种颜色就会占据第i行第j列,其他颜色不能往这儿放 设 ...
- [洛谷P3158] [CQOI2011]放棋子
洛谷题目链接:[CQOI2011]放棋子 题目描述 在一个m行n列的棋盘里放一些彩色的棋子,使得每个格子最多放一个棋子,且不同 颜色的棋子不能在同一行或者同一列.有多少祌方法?例如,n=m=3,有两个 ...
- 【BZOJ 3294】 3294: [Cqoi2011]放棋子 (DP+组合数学+容斥原理)
3294: [Cqoi2011]放棋子 Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数 ...
- P3158 [CQOI2011]放棋子(dp+组合数)
P3158 [CQOI2011]放棋子 放棋子的顺序和方案数无关,所以可以从按颜色递推 设$f[u][p][k]$为放到第$u$种颜色,所剩空间$p*k$的方案数 $g[u][i][j]$表示第$u$ ...
- BZOJ3294: [Cqoi2011]放棋子
Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数保证不超过nm. Output 输出 ...
- [CQOI2011]放棋子--DP
题目描述: 输入格式 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数保证不超过nm.N,M<=30 C<=10 ...
随机推荐
- 01-springboot整合elasticsearch初识
1.elasticsearch 1.es简介 Elasticsearch 是一个分布式.高扩展.高实时的搜索与数据分析引擎.它能很方便的使大量数据具有搜索.分析和探索的能力.充分利用Elas ...
- sql语句replace函数的使用
SQL中的替换函数replace()使用 语法 REPLACE ( string_expression , string_pattern , string_replacement ) 参数 strin ...
- 一文了解HAProxy主要特性
本文转自Rancher Labs 在Kubernetes中,Ingress对象定义了一些路由规则,这些规则规定如何将一个客户端请求路由到指定服务,该服务运行在你的集群中.这些规则可以考虑到输入的HTT ...
- day31 反射,内置方法,元类
目录 一.反射 1 什么是反射 2 如何实现反射 二.内置方法 1 什么是内置方法 2 为什么要用内置方法 3 如何使用内置方法 3.1 str 3.2 del 三.元类 1 什么是元类 2 clas ...
- JVM 专题二十一:垃圾回收(五)垃圾回收器 (二)
3. 回收器 3.1 Serial回收器:串行回收 3.1.1 概述 Serial收集器是最基本.历史最悠久的垃圾收集器了.JDK1.3之前回收新生代唯一的选择. Serial收集器作为Hotspot ...
- 数据可视化实例(十四):带标记的发散型棒棒糖图 (matplotlib,pandas)
偏差 (Deviation) 带标记的发散型棒棒糖图 (Diverging Lollipop Chart with Markers) 带标记的棒棒糖图通过强调您想要引起注意的任何重要数据点并在图表中适 ...
- IDEA搭建SpringMVC简单接口框架(Maven项目)
1, 新建项目,选择Maven,如图一次选择,最后点击Next 2, 输入GroupId和ArtifactId,点击Next 3,根据需要选择自定义maven配置,点击Next.(①可以直接跳过) 4 ...
- python---Flask使用教程-加载静态文件
flask的静态文件,一般放在static目录下,前端页面放在templates下(而且这两个名字是定死的(static,templates)),目录结构如图: 模板(index.html)里加载静态 ...
- 如何将你写的脚本程序打包成一个exe可执行程序
编写的程序打包成一个exe文件,随时可以双击执行,想想是不是很酷.接下来我们一起看一下如何将自己编写的程序打包为一个exe的可执行程序. 将程序打包成exe的好处 除了满足自己的成就感以外, ...
- 数据源管理 | 搜索引擎框架,ElasticSearch集群模式
本文源码:GitHub·点这里 || GitEE·点这里 一.集群环境搭建 1.环境概览 ES版本6.3.2,集群名称esmaster,虚拟机centos7. 服务群 角色划分 说明 en-maste ...