题面传送门

本来说要找道轮廓线 \(dp\) 的题目刷刷来着的?然后就找到了这道题。

然鹅这个题给我最大的启发反而不在轮廓线 \(dp\),而在于让我新学会了一个玩意儿叫做 Min-Max 容斥。

Min-Max 容斥大概讲的就是这样一件事情:对于任意集合 \(S\),\(\max(S)=\sum\limits_{T\subseteq S,T\ne\varnothing}(-1)^{|T|-1}\min(T)\),因为这个式子包含容斥系数 \((-1)^{|T|-1}\) 和集合的 \(\min,\max\),因此被称为 Min-Max 容斥。

证明还算容易,假设 \(S\) 中的元素从小到大依次为 \(a_1,a_2,\cdots,a_n\),考虑每个 \(a_i\) 作为最小值出现的贡献,显然 \(a_n\) 的贡献就是 \(a_n\),因为它只能在 \(T=\{a_n\}\) 中作为最小值,而对于 \(i<n\),\(a_i\) 为 \(T\) 的最小值当且仅当 \(T\) 可以写成 \(\{a_i\}\cup T'\) 的形式,其中 \(T'\subseteq\{a_{i+1},a_{i+2},\cdots,a_n\}\),考虑枚举 \(T'\) 的大小 \(s\),那么共有 \(\dbinom{n-i}{s}\) 个可选的 \(T'\),它们的贡献均为 \((-1)^s\),故总贡献为 \(\sum\limits_{i=0}^{n-i}\dbinom{n-i}{s}(-1)^s=0^{n-i}=0\),故总贡献就是 \(a_n=\max(S)\)。

接下来考虑怎样将 Min-Max 容斥使用到这道题上,我们考虑将所有 * 格子编个号,记 \(t_i\) 为编号为 \(i\) 的 * 格第一次被覆盖的时间,那么题目要求的值即为 \(E(\max\{t_i\})\),我们知道对于这样的集合,\(\max\) 是不太好求的,不过 \(E(\min\{t_i\})\) 非常好求,记 \(C\) 为有多少个 \(1\times 2\) 的矩形包含至少一个 * 格,\(D\) 为总共有多少个 \(1\times 2\) 的矩形(显然 \(D=n(m-1)+m(n-1)\)),那么 \(E(\min\{t_i\})=\dfrac{C}{D}\)。因此考虑套用 Min-Max 容斥,记 \(S\) 为 \(t_i\) 组成的集合所有,那么 \(E(\max(S))=\sum\limits_{T\subseteq S}(-1)^{T-1}E(\min(T))\)。直接枚举子集显然是不行的,不过我们发现 \(E(\min\{t_i\})\) 的表达式中,\(D\) 为定值,而 \(C\) 的范围也不会太大,最多不过 \(1200\),因此我们考虑转而枚举 \(C\) 并预处理所有子集 \(T\) 满足其对应的 \(C\) 为我们枚举的值的贡献之和。这东西怎么预处理呢?就要用到我们一开始说的轮廓线 \(dp\) 了,记 \(dp_{i,j,k,l}\) 为考虑了前 \(i\) 列,第 \(i\) 列考虑到了第 \(j\) 行,轮廓线左侧取/不取的状态为 \(k\),有 \(l\) 个 \(1\times 2\) 的矩形包含了至少一个 \(T\) 中的格子的所有子集 \(T\) 的 \((-1)^{|T|-1}\) 之和。搞清楚状态之后转移应该就比较容易了,具体见代码罢。

时间复杂度 \(n^2m^22^n\)。

最后总结一个小 trick,碰到那种形如求 \(E(\max(S))\) 的题目,如果 \(E(\min(S))\) 比较容易求得,那么可以考虑 Min-Max 容斥。

const int MAXN=6;
const int MAXM=100;
const int MAXP=64;
const int MAXCNT=1200;
const int MOD=998244353;
void inc(int &x,int y){((x+=y)>=MOD)&&(x-=MOD);}
int n,m,inv[MAXCNT+5];char s[MAXN+5][MAXM+5];
int dp[MAXM+5][MAXN+5][MAXP+5][MAXCNT+5];
int main(){
scanf("%d%d",&n,&m);int cnt=n*(m-1)+m*(n-1);inv[1]=1;
for(int i=2;i<=cnt;i++) inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
dp[1][1][0][0]=1;if(s[1][1]=='*') dp[1][1][1][0]=MOD-1;
for(int i=1;i<=m;i++) for(int j=1;j<=n;j++)
for(int k=0;k<(1<<n);k++) for(int l=0;l<=cnt;l++){
if(i==m&&j==n) continue;
if(!dp[i][j][k][l]) continue;
int ni=(j==n)?i+1:i,nj=j%n+1,add=0;
if(s[nj][ni]=='*')
inc(dp[ni][nj][k|(1<<nj-1)][l+(ni!=1)+(nj!=1)],MOD-dp[i][j][k][l]);
if((k>>j-1&1)&&(nj!=1)) add++;
if((k>>nj-1&1)) add++;
inc(dp[ni][nj][k&(~(1<<nj-1))][l+add],dp[i][j][k][l]);
}
int ans=0;
for(int i=1;i<=cnt;i++) for(int j=0;j<(1<<n);j++)
ans=(ans+1ll*dp[m][n][j][i]*inv[i]%MOD*cnt)%MOD;
printf("%d\n",MOD-ans);
return 0;
}

UOJ 422 - 【集训队作业2018】小Z的礼物(Min-Max 容斥+轮廓线 dp)的更多相关文章

  1. UOJ 422 [集训队作业2018] 小Z的礼物 min-max容斥 期望 轮廓线dp

    LINK:小Z的礼物 太精髓了 我重学了一遍min-max容斥 重写了一遍按位或才写这道题的. 还是期望多少时间可以全部集齐. 相当于求出 \(E(max(S))\)表示最后一个出现的期望时间. 根据 ...

  2. [UOJ422][集训队作业2018]小Z的礼物——轮廓线DP+min-max容斥

    题目链接: [集训队作业2018]小Z的礼物 题目要求的就是最后一个喜欢的物品的期望得到时间. 根据$min-max$容斥可以知道$E(max(S))=\sum\limits_{T\subseteq ...

  3. uoj#422. 【集训队作业2018】小Z的礼物(MIn-Max容斥+插头dp)

    题面 传送门 题解 好迷-- 很明显它让我们求的是\(Max(S)\),我们用\(Min-Max\)容斥,因为\(Min(S)\)是很好求的,只要用方案数除以总方案数算出概率,再求出倒数就是期望了 然 ...

  4. 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)

    [UOJ#422][集训队作业2018]小Z的礼物(min-max容斥,轮廓线dp) 题面 UOJ 题解 毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ 一开始开错题了,根本就不会做. 后来发现是每次 ...

  5. UOJ 449 【集训队作业2018】喂鸽子 【生成函数,min-max容斥】

    这是第100篇博客,所以肯定是要水过去的. 首先看到这种形式的东西首先min-max容斥一波,设\(f_{c,s}\)表示在\(c\)只咕咕中,经过\(s\)秒之后并没有喂饱任何一只的概率. \[ \ ...

  6. [集训队作业2018]蜀道难——TopTree+贪心+树链剖分+链分治+树形DP

    题目链接: [集训队作业2018]蜀道难 题目大意:给出一棵$n$个节点的树,要求给每个点赋一个$1\sim n$之内的权值使所有点的权值是$1\sim n$的一个排列,定义一条边的权值为两端点权值差 ...

  7. uoj #450[集训队作业2018]复读机

    传送门 \(d=1\),那么任何时刻都可以\(k\)个复读机的一种,答案为\(k^n\) \(d>1\),可以枚举某个复读机的复读次数(必须是\(d\)的倍数),然后第\(i\)个复读时间为\( ...

  8. UOJ#422. 【集训队作业2018】小Z的礼物

    #422. [集训队作业2018]小Z的礼物 min-max容斥 转化为每个集合最早被染色的期望时间 如果有x个选择可以染色,那么期望时间就是((n-1)*m+(m-1)*n))/x 但是x会变,中途 ...

  9. 2019.2.25 模拟赛T1【集训队作业2018】小Z的礼物

    T1: [集训队作业2018]小Z的礼物 我们发现我们要求的是覆盖所有集合里的元素的期望时间. 设\(t_{i,j}\)表示第一次覆盖第i行第j列的格子的时间,我们要求的是\(max\{ALL\}\) ...

随机推荐

  1. FastAPI 学习之路(三十七)元数据和文档 URL

    你可以在 FastAPI 应用中自定义几个元数据配置. 你可以设定: Title:在 OpenAPI 和自动 API 文档用户界面中作为 API 的标题/名称使用. Description:在 Ope ...

  2. 【UE4 C++ 基础知识】<9> Interface 接口

    概述 简单的说,接口提供一组公共的方法,不同的对象中继承这些方法后可以有不同的具体实现. 任何使用接口的类都必须实现这些接口. 实现解耦 解决多继承的问题 蓝图使用 使用方法 三种调用方法的区别 调用 ...

  3. 对比7种分布式事务方案,还是偏爱阿里开源的Seata,真香!(原理+实战)

    前言 这是<Spring Cloud 进阶>专栏的第六篇文章,往期文章如下: 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强? openFeign夺命连环9问,这谁受得了? 阿里面 ...

  4. JVM:体系结构

    JVM:体系结构 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 概览 Java GC 主要回收的是 方法区 和 堆 中的内容 类加载器 类加载器是什么 双亲委派 ...

  5. Java:包装类小记

    Java:包装类 对 Java 中的 包装类 这个概念,做一个微不足道的小小小小记 基本数据&包装类 四类八种基本数据类型: 数据类型 关键字 内存占用 取值范围 字节型 byte 1个字节 ...

  6. Scrum Meeting 13

    第13次例会报告 日期:2021年06月05日 会议主要内容概述: 团队成员均明确了下一步的目标,进度突飞猛进辣 一.进度情况 我们采用日报的形式记录每个人的具体进度,链接Home · Wiki,如下 ...

  7. UltraSoft - Alpha - Scrum Meeting 7

    Date: Apr 22th, 2020. Scrum 情况汇报 进度情况 组员 负责 昨日进度 后两日任务 CookieLau PM 完成课程中心的json格式传递 完成邮箱验证机制 刘zh 前端 ...

  8. [no_code]OCR表格处理——功能规格说明书

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 功能规格说明书 我们在这个课程的目标是 远程协同工作,采用最新技术开发软件 这个作业在哪个具体方面 ...

  9. HDI PCB一阶和二阶和三阶如何区分??

      一阶板,一次压合即成,可以想像成最普通的板二阶板,两次压合,以盲埋孔的八层板为例,先做2-7层的板,压好,这时候2-7的通孔埋孔已经做好了,再加1层和8层压上去,打1-8的通孔,做成整板.三阶板就 ...

  10. 数据流中的中位数 牛客网 剑指Offer

    数据流中的中位数 牛客网 剑指Offer 题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就 ...