概念

Min-Max容斥,又称最值反演,是一种对于特定集合,在已知最小值或最大值中的一者情况下,求另一者的算法。

例如:

\[max(a,b)=a+b-min(a,b) \\ max(a,b,c)=a+b+c-min(a,b)-min(a,c)-min(b,c)+min(a,b,c)
\]

显然,将所有数取相反数,易知用最大值求最小值的公式与用最小值求最大值的公式形式相同。以下只讨论用最小值求最大值的方法。

形式

记 \(Max(S)\) 表示集合 \(S\) 的最大值,\(Min(S)\) 表示集合 \(S\) 的最小值,则:

\[Max(S)=\sum\limits_{T\subset S,T\neq \phi}(-1)^{|T|-1}Min(T)
\]

推导

设存在一个以集合大小为自变量的函数 \(f\) 满足 \(Max(S)=\sum\limits_{T\subset S,T\neq \phi}f(|T|)Min(T)\) 。

记 \(S\) 中元素从大到小排列为 \(x_1,x_2,...,x_m\) ,则对于 \(x_i\) ,其在左侧的贡献为 \([i=1]\) ,在右侧的贡献为 \(\sum\limits_{j=0}^{i-1}{i-1\choose j}f(j+1)\) 。

若等式成立,则必有 \([i=1]=\sum\limits_{j=0}^{i-1}{i-1\choose j}f(j+1)\) 。

设 \(F(i)=[i+1=1]\) (即 \([i=1]=F(i-1)\) ),\(G(i)=f(i+1)\) ,则 \(F(i)=\sum\limits_{j=0}^{i}{i\choose j}G(j)\) 。

进行二项式反演,得 \(G(i)=\sum\limits_{j=0}^{i}(-1)^{i-j}{i\choose j}F(j)=(-1)^i\) 。

故 \(f(i)=G(i-1)=(-1)^{i-1}\) 。

因此构造成立,故:

\[Max(S)=\sum\limits_{T\subset S,T\neq \phi}(-1)^{|T|-1}Min(T)
\]

另一种证明

考虑等式右侧,记最小值为 \(x_i\) ,则:

  • 当 \(i=1\) 时,贡献为 \(1\) ;
  • 当 \(i\neq 1\) 时,则 \(x_1\) 有选和不选两种方案,这两种方案一一对应且系数恰为相反数,故总贡献为 \(0\) 。

故右侧的总和就是 \(x_1=Max(S)\) 。

推广

记 \(kMax(S)\) 表示集合 \(S\) 的第 \(k\) 大值,则:

\[kMax(S)=\sum\limits_{T\subset S,|T|\ge k}(-1)^{|T|-k}{|T|-1\choose k-1}Min(T)
\]

推导

设存在一个以集合大小为自变量的函数 \(g\) 满足 \(kMax(S)=\sum\limits_{T\subset S,T\neq \phi}g(|T|)Min(T)\) 。

记 \(S\) 中元素从大到小排列为 \(x_1,x_2,...,x_m\) ,则对于 \(x_i\) ,其在左侧的贡献为 \([i=k]\) ,在右侧的贡献为 \(\sum\limits_{j=0}^{i-1}{i-1\choose j}g(j+1)\) 。

若等式成立,则必有 \([i=k]=\sum\limits_{j=0}^{i-1}{i-1\choose j}g(j+1)\) 。

设 \(F(i)=[i+1=k]\) (即 \([i=k]=F(i-1)\) ),\(G(i)=g(i+1)\) ,则 \(F(i)=\sum\limits_{j=0}^{i}{i\choose j}G(j)\) 。

进行二项式反演,得 \(G(i)=\sum\limits_{j=0}^{i}(-1)^{i-j}{i\choose j}F(j)=(-1)^{i-k+1}{i\choose k-1}\) 。

故 \(f(i)=G(i-1)=(-1)^{i-k}{i-1\choose k-1}\) 。

因此构造成立,故:

\[kMax(S)=\sum\limits_{T\subset S,|T|\ge k}(-1)^{|T|-k}{|T|-1\choose k-1}Min(T)
\]

应用

Min-Max容斥及其推广常用于解决“都出现的期望时间”问题,处理方法:

记 \(t_i\) 表示第 \(i\) 个元素的出现时间,则:

  • \(Max(S)\) 表示 \(S\) 中 \(t\) 的最大值,即所有元素出现时间的最大值,即所有元素都出现的时间;
  • \(Min(S)\) 表示 \(S\) 中 \(t\) 的最小值,即所有元素出现时间的最小值,即至少有一个出现的时间。

根据Min-Max容斥,有 \(Max(S)=\sum\limits_{T\subset S,T\neq \phi}(-1)^{|T|-1}Min(T)\) 。

对左右同时取期望,由于线性,期望可以直接放到求和符号里面,即 \(E(Max(S))=\sum\limits_{T\subset S,T\neq \phi}(-1)^{|T|-1}E(Min(T))\) 。

容易发现 \(E(Min(T))\) 求起来十分容易:当单位时间出现 \(T\) 中至少一个的概率为 \(p\) ,则出现 \(T\) 中至少一个的期望时间为 \(\frac 1p\) 。

于是通过公式即可求出 \(Max(S)\) ,即所有元素都出现的期望时间。

对于Min-kMax容斥同理。

写法

如果只需要求出 \(Max(U)\) ,即全集的最大值的话,只需要计算每个自己对全集的贡献即可。

如果要对所有 \(S\) 求 \(Max(S)\) 的话(尽管似乎还没遇到过),一种较快的方法是用按位分治来代替枚举子集。有两种常用写法,它们稍加处理就可以变成公式中的形式。

写法一

for(i = 1 ; i < (1 << n) ; i <<= 1)
for(j = 0 ; j < (1 << n) ; j ++ )
if(j & i)
f[j] -= f[i];

此时系数是 \((-1)^{|S|-|T}\) .

写法二

for(i = 1 ; i < (1 << n) ; i <<= 1)
for(j = 0 ; j < (1 << n) ; j ++ )
if(j & i)
f[j] = f[i] - f[j];

此时系数是 \((-1)^{|T|}\) 。

例题

[hdu4336]Card Collector

题目大意

有 \(n\) 种卡片,每次购买有 \(p_i\) 的概率买到第 \(i\) 种,求使得每种都买到的期望购买次数。

\(1\le n\le 20\) 。

题解

Min-Max容斥基础题,参见上面的 “应用” 部分。

对于本题,有 \(Min(S)=\frac 1{\sum\limits_{i\in S}p_i}\) ,然后套用 \(Min-Max\) 容斥的公式即可。

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

#include <cstdio>
#define N 1100010
int cnt[N];
double p[N] , f[N];
int main()
{
int n , i , j;
double ans;
while(~scanf("%d" , &n))
{
ans = 0;
for(i = 0 ; i < n ; i ++ ) scanf("%lf" , &p[1 << i]);
for(i = 1 ; i < (1 << n) ; i ++ ) f[i] = f[i - (i & (-i))] + p[i & (-i)] , cnt[i] = cnt[i - (i & -i)] + 1;
for(i = 1 ; i < (1 << n) ; i ++ ) ans += ((cnt[i] & 1) ? 1 : -1) / f[i];
printf("%lf\n" , ans);
}
return 0;
}

[bzoj4036]按位或

题目大意

你初始有数字 \(0\) ,每次操作会随机选择 \([0,2^n-1]\) 的一个数字与你的数字进行按位或运算,选到数 \(i\) 的概率为 \(p_i\) 。求使得你的数字变为 \(2^n-1\) 的期望操作次数。

\(1\le n\le 20\) 。

题解

和上一题类似,问题转化为计算 \(Min(S)\) ,即需要求出所有与 \(S\) 有公共元素(取与不为 \(0\) )的 \(p\) 之和。

正难则反,考虑求所有与 \(S\) 无公共元素的 \(p\) 之和,即 \(S\) 的补集 \(2^n-1-S\) 的所有子集的 \(p\) 之和,使用按位分治来解决。

最后套公式计算即可。无解的判定通过判断是否某一位都存在一个 \(p\neq 0\) 的元素来处理。

时间复杂度 \(O(n\times 2^n)\) 。

代码

#include <cstdio>
#include <algorithm>
using namespace std;
double p[1100010];
int cnt[1100010];
int main()
{
int n , i , j;
double ans = 0;
scanf("%d" , &n);
for(i = 0 ; i < (1 << n) ; i ++ ) scanf("%lf" , &p[i]);
for(i = 1 ; i < (1 << n) ; i ++ ) cnt[i] = cnt[i - (i & -i)] + 1;
for(i = 1 ; i < (1 << n) ; i <<= 1)
{
for(j = 0 ; j < (1 << n) ; j ++ )
if((j & i) && p[j])
break;
if(j == (1 << n))
{
puts("INF");
return 0;
}
}
for(i = 1 ; i < (1 << n) ; i <<= 1)
for(j = 0 ; j < (1 << n) ; j ++ )
if(j & i)
p[j] += p[j ^ i];
for(i = 1 ; i < (1 << n) ; i ++ ) ans += ((cnt[i] & 1) ? 1 : -1) / (1 - p[(1 << n) - 1 - i]);
printf("%.8lf\n" , ans);
return 0;
}

[luogu4707]重返现世

题目大意

有 \(n\) 种物质,每单位时间会随机生成一种物质,生成第 \(i\) 种物质的概率为 \(\frac{p_i}m\) 。求获得 \(k\) 种物质的期望时间。

\(1\le n\le 1000\) ,\(1\le m\le 10000\) ,\(1\le k\le n\) ,\(p_i\) 为整数且 \(\sum\limits_{i=1}^np_i=m\) ,\(n-k\le 10\) 。

题解

获得 \(k\) 种物质,相当于求所有获得时间中第 \(n-k+1\) 大的,问题转化为Min-kMax容斥问题。方便起见,以下令 \(q=n-k+1\) ,则有 \(1\le q\le 11\) 。

由于 \(n\) 有 \(1000\) 之大,使用前两道题的子集统计方法显然会直接暴毙。

思考:尽管我们的集合选取方案有 \(2^n\) 种,但每种的 \(Min(S)\) 只和 \(\sum\limits_{i\in S}p_i\) 有关,因此状态数其实只有 \(m\) 种。

一个比较显然的思路是设 \(f_{i,j,l}\) 表示前 \(i\) 种物质选出 \(j\) 种,凑齐 \(\sum p=l\) 的方案数,然而数据范围过大,无法通过此题。

到此为止,我们还有一个条件没有用到:\(q\le 11\) 。

考虑在已知 \(f_{i,j,l}\) 后答案的计算,贡献为 \((-1)^{j-q}{j-1\choose q-1}\times \frac ml\times f_{i,j,l}\) 。对于前面的部分,运用组合数公式,有:

\[(-1)^{j-q}{j-1\choose q-1}=(-1)^{(j-1)-(q-1)}{j-2\choose q-2}-(-1)^{(j-1)-q}{j-2\choose q-1}
\]

而 \(f_{i,j,l}\) 又有转移 \(f_{i,j,l}=f_{i-1,j,l}+f_{i-1,j-1,l-p_i}\) ,故:

\[(-1)^{j-q}{j-1\choose q-1}f_{i,j,l}=(-1)^{j-q}{j-1\choose q-1}f_{i-1,j,l}+(-1)^{(j-1)-(q-1)}{j-2\choose q-2}f_{i-1,j-1,l-p_i}-(-1)^{(j-1)-q}{j-2\choose q-1}f_{i-1,j-1,l-p_i}
\]

发现了什么?前面的系数只和 \(j\) 与计算答案时所用的 \(q\) 有关,因此设 \(g_{i,j,l,t}\) 表示前 \(i\) 种物质选出 \(j\) 种,凑齐 \(\sum p=l\) ,且最终计算时的 \(q=t\) 的系数乘以方案数。则有:

\[g_{i,j,l,t}=g_{i-1,j,l,t}+g_{i-1,j-1,l-p_i,t-1}-g_{i-1,j-1,l-p_i,t}
\]

我们所做的似乎都是无用功。但事实上,仔细观察就会发现 \(j\) 的一维已经没有用处,无论是转移还是最终答案都不需要用到 \(j\)。

左右对 \(j\) 那一维求和,便有 \(h_{i,l,t}\) 表示前 \(i\) 种物质选出若干种,凑齐 \(\sum p=l\) ,且最终计算时的 \(q=t\) 的系数乘以方案数,则有:

\[h_{i,l,t}=h_{i-1,l,t}+h_{i-1,l-p_i,t-1}-h_{i-1,l-p_i,t}
\]

最终答案就是 \(\sum\limits_{i=1}^mh_{n,i,q}\times \frac mi\) 。

时间复杂度 \(O(nmq)\) ,由于空间不足,需要使用滚动数组。

代码

#include <cstdio>
#include <cstring>
#define mod 998244353
typedef long long ll;
ll p[1010] , f[2][10010][11];
inline ll qpow(ll x , ll y)
{
ll ans = 1;
while(y)
{
if(y & 1) ans = ans * x % mod;
x = x * x % mod , y >>= 1;
}
return ans;
}
int main()
{
int n , t , m , i , j , k , d;
ll ans = 0;
scanf("%d%d%d" , &n , &t , &m) , t = n - t + 1;
for(i = 1 ; i <= n ; i ++ ) scanf("%lld" , &p[i]);
for(i = 1 ; i <= t ; i ++ ) f[0][0][i] = -1;
for(d = i = 1 ; i <= n ; i ++ , d ^= 1)
{
memcpy(f[d] , f[d ^ 1] , sizeof(f[d]));
for(j = p[i] ; j <= m ; j ++ )
for(k = 1 ; k <= t ; k ++ )
f[d][j][k] = (f[d][j][k] + f[d ^ 1][j - p[i]][k - 1] - f[d ^ 1][j - p[i]][k] + mod) % mod;
}
for(i = 1 ; i <= m ; i ++ ) ans = (ans + f[n & 1][i][t] * m % mod * qpow(i , mod - 2)) % mod;
printf("%lld\n" , ans);
return 0;
}

Min-Max容斥及其推广和应用的更多相关文章

  1. min-max 容斥

    $\min - \max$ 容斥 Part 1 对于简单的$\min - \max$容斥有一般形式,表达为:$\max(S)=\sum\limits_{T\subseteq S}(-1)^{|T|-1 ...

  2. Min-max 容斥与 kth 容斥

    期望的线性性: \[E(x+y)=E(x)+E(y) \] 证明: \[E(x+y)=\sum_i \sum_j(i+j)*P(i=x,j=y) \] \[=\sum_i\sum_ji*P(i=x,j ...

  3. min-max容斥学习笔记

    min-max容斥学习笔记 前置知识 二项式反演 \[ f(n)=\sum_{i=0}^n\binom{n}{i}g(i)\Leftrightarrow g(n)=\sum_{i=0}^n(-1)^{ ...

  4. [学习笔记]min-max容斥

    [Learning]min-max容斥以及推广 min-max容斥 就是max(a,b)=min(a)+min(b)-min(a,b) max(a,b,c)=a+b+c-min(a,b)-min(a, ...

  5. [模板] 容斥原理: 二项式反演 / Stirling 反演 / min-max 容斥 / 子集反演 / 莫比乌斯反演

    //待更qwq 反演原理 二项式反演 若 \[g_i=\sum_{j=1}^i {\binom ij} f_j\] , 则有 \[ f_i=\sum_{j=1}^i (-1)^{i-j} {i \ch ...

  6. [总结] Min-Max容斥学习笔记

    min-max 容斥 给定集合 \(S\) ,设 \(\max(S)\) 为 \(S\) 中的最大值,\(\min(S)\) 为 \(S\) 中的最小值,则: \[\max(S)=\sum_{T\in ...

  7. MinMax 容斥 学习笔记

    基本形式 \[ \max(S) = \sum_{T\subseteq S, T \neq \varnothing} (-1)^{|T|-1}\min(T) \] 证明 不提供数学证明. 简要讲一下抽象 ...

  8. HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

    题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...

  9. UVa12633 Super Rooks on Chessboard(容斥 + FFT)

    题目 Source http://acm.hust.edu.cn/vjudge/problem/42145 Description Let’s assume there is a new chess ...

随机推荐

  1. MVC开发中自定义返回类型

    在做项目web的MVC中,会用到返回值的问题,我们一般使用AjaxResult的返回值,根据自己的需要进行自定义,如下参考: using System; using System.Collection ...

  2. hive删除数据(转)

    转自:https://www.cnblogs.com/linn/p/6196293.html 按分区删除: ALTER TABLE test1  DROP PARTITION (dt='2016-04 ...

  3. spark-shell操作hive

    本文是在集群已经搭建好的基础上来说的,还没有搭建好集群的小伙伴还请自行百度! 启动spark-shell之前要先启动hive metastore 和 hiveservice2 hive --servi ...

  4. Linux计划作业练习

    1.crontab -eu zh  //每天晚上10天提醒用户可以去睡觉了 * */10  * *  * go to sleep 2.查询crontab的工作内容 3.当crontab命令格式出错时 ...

  5. python - 将数据转换成 excl 表格, json 等文件 (dajngo - 打开网页后自动下载)

    本篇只讲述怎么用. 具体 tablib  更多详细用法可参考博客 : https://blog.csdn.net/liangyuannao/article/details/41476277 # 不得不 ...

  6. Nginx 代理到Jetty 页面跳转端口改变问题

    Nginx安装 Windows下部署Nginx只需下载安装包,解压启动服务器即可.下载官网:http://nginx.org/en/download.html 操作Nginx首先进入安装文件夹: 查看 ...

  7. 第04组alpha冲刺(3/4)

    队名:斗地组 组长博客:地址 作业博客:Alpha冲刺(3/4) 各组员情况 林涛(组长) 过去两天完成了哪些任务: 1.收集各个组员的进度 2.写博客 展示GitHub当日代码/文档签入记录: 接下 ...

  8. http响应消息

    1. 请求消息:客户端发送给服务器端的数据 * 数据格式: 1. 请求行 2. 请求头 3. 请求空行 4. 请求体 2. 响应消息:服务器端发送给客户端的数据 * 数据格式: 1. 响应行 1. 组 ...

  9. GoCN每日新闻(2019-11-08)

    GoCN每日新闻(2019-11-08) GoCN每日新闻(2019-11-08) 1. Go Modules: v2及更高版本使用 https://blog.golang.org/v2-go-mod ...

  10. ssl 原理简介

    要想弄明白SSL认证原理,首先要对CA有有所了解,它在SSL认证过程中有非常重要的作用.说白了,CA就是一个组织,专门为网络服务器颁发证书的,国际知名的CA机构有VeriSign.Symantec,国 ...