Min-Max 容斥

亿些废话

上课听 lf 说到「莫比乌斯反演」,「FWT/FMT」,「生成函数」这些什么的都讲过我就很头大,数学这坑是得有多大啊。

不过 lf 说不久后就开始复习网络流,好歹算是有点空闲时间可以补数学了。

前置芝士

要会基本的容斥,以及二项式定理。

如果你不会的话可以看看我写的二项式反演广义容斥原理,上面两个东西在这两篇博客中都有讲到。

Min-Max 容斥

也叫「最值反演」,就是在你知道一个集合所有子集的最小值(或最大值)时,可以通过它们反演出这个集合的最大值。

听起来很弱智对吧,从直觉上来说你可以直接这么干:

$$ \begin{aligned} \max(S) = \max\limits_{T \in S}\left\{\min(T)\right\}\\ \min(S) = \min\limits_{T \in S}\left\{\max(T)\right\} \end{aligned} $$

你说得对,但是 Min-Max 容斥长成这个样子:

$$ \begin{aligned} \max(S) = \sum\limits_{T \in S}(-1)^{|T| - 1}\min(T)\\ \min(S) = \sum\limits_{T \in S}(-1)^{|T| - 1}\max(T) \end{aligned} $$

第一眼觉得这个柿子好神奇,可以把最值转化成求和。(事实上 Min-Max 容斥神奇的原因就是这个。)

让我们证明一下(以通过最小值反演出最大值为例):

首先将集合内的数从大到小排序,现在将它们记为 $s_{1}, s_{2}, s_{3}, \cdots, s_{|S|}(\forall i\in\left[1, |S|\right) s_{i} \geqslant s_{i + 1})$。

依次考虑每个数在上面的柿子中的贡献。

一个数要想作为最小值被计算,那么在某个子集中,最小值会在其中出现,并且剩下的数只能是在这个最小值前面的数,否则最小值就不是这个数了。

所以我们可以写出第 $i$ 个数的贡献:

$$ \begin{aligned} &\sum\limits_{T \in \left\{s_{1}, s_{2}, \cdots, s_{i - 1}\right\}}(-1)^{|T| + 2}s_{i}\\ =&s_{i}\sum\limits_{T \in \left\{s_{1}, s_{2}, \cdots, s_{i - 1}\right\}}(-1)^{|T| + 2}\\ \end{aligned} $$

发现后面那一坨柿子和具体的 $T$ 集合长成什么样无关,我们只用考虑 $|T|$ 即可,于是改写成下面这种形式:

$$ \begin{aligned} &s_{i}\sum\limits_{j = 0}^{i - 1}\binom{i - 1}{j}(-1)^{j + 2}\\ =&s_{i}\sum\limits_{j = 0}^{i - 1}\binom{i - 1}{j}(-1)^{j}\\ \end{aligned} $$

然后发现后面这一坨可以用二项式定理化成 $(1 - 1)^{i - 1} = [i = 1]$。

于是,$s_{1}$ (也就是最大值)的贡献为 $s_{1}$,而其它数的贡献为 $0$。证毕。

最小值类似。

那么这个看起来很弱智并且时间复杂度还不优的东西有什么用呢。

根据期望的线性性,Min-Max 容斥在期望上也是成立的,所以:

$$ \begin{aligned} E\big(\max(S)\big) = \sum\limits_{T \in S}(-1)^{|T| - 1}E\big(\min(T)\big)\\ E\big(\min(S)\big) = \sum\limits_{T \in S}(-1)^{|T| - 1}E\big(\max(T)\big) \end{aligned} $$

于是在遇到求「最大值的期望」不方便的时候,可以尝试求「最小值的期望」来容斥出「最大值的期望」。

既然这个东西是容斥,那它是不是也满足广义容斥原理呢?答案是肯定的,这种情况就是求 kth max/kth min 了。

这个东西等我以后再来补吧。


例题

都是拿来求期望的,所以还需要一定的概率/期望 dp 基础。

「HDU 4336」Card Collector

题目大意:有 $n$ 种卡片,第 $i$ 种卡片在一包零食中出现的概率为 $p_{i}$,并且每包零食中至多出现一张卡片,问你集齐所有的卡片需要购买零食数量的期望。

这道题有一个 $\mathcal{O}(n2^{n})$的状压 dp 做法,但是我不讲。

考虑 Min-Max 容斥:

我们把买来的零食按买入的顺序排成一排,令 $t_{i}$ 表示第 $i$ 种卡片第一次出现是在第 $t_{i}$ 包零食中,于是我们就要求 $E\big(\max\limits_{1 \leqslant i \leqslant n}t_{i}\big)$。

但是直接求「最大值的期望」并不方便,用 Min-Max 容斥转化成求「最小值的期望」。

于是有:

$$ E\big(\max(S)\big) = \sum\limits_{T \in S}(-1)^{|T| - 1}E\big(\min(T)\big) $$

直接枚举子集 $T$,现在考虑求 $E\big(\min(T)\big)$,其本质就是问:你第一次拿到属于这个集合的卡片所要买的零食数量。

买一包零食,我们拿到属于这个集合的卡片的概率为 $\sum\limits_{i \in T}p_{i}$,现在来求期望。

(其实这里写为 $\sum\limits_{i \in T}p_{i}$ 是不够严谨的,因为 $T$ 集合里面是 $t_{i}$ 而不是 $i$,但是我一时没想到更好的表达方法于是就这么写了,相信大家能看懂。)

我推到这里就不会了,因为这种看起来可以无限进行下去的东西对我来说实在太抽象了,尽管我知道它是收敛的。问了一下 cgy,他给了我两种做法,我觉得都挺容易理解的,于是就都写一下:

  1. 直接暴力地写成求和式。

(下文的 $p$ 默认为 $\sum\limits_{i \in T}p_{i}$。)

我们其实是要求:

$$ \sum\limits_{i = 1}^{+\infty}(1 - p)^{i - 1} \times p \times i $$

(如果写成 $\sum\limits_{i = 1}^{+\infty}(1 - p)^{i - 1} \times p$ 的话那想必大家都知道是 $1$,因为概率和为 $1$)

考虑把 $p$ 提到外面来:

$$ p \times \sum\limits_{i = 1}^{+\infty}(1 - p)^{i - 1} \times i $$

现在重心转移到求后面这一坨柿子上面,我们把它的每一项写下来,排成一个数列:

$$ 1, 2(1 - p), 3(1 - p)^{2}, 4(1 - p)^{3}, \cdots $$

给它减去一个 $\sum\limits_{i = 1}^{+\infty}(1 - p)^{i - 1}$(一个等比数列),数列就变成了:

$$ 0, (1 - p), 2(1 - p)^{2}, 3(1 - p)^{3}, \cdots $$

现在,给它除一个 $1 - p$,变成:

$$ 1, 2(1 - p), 3(1 - p)^{2}, 4(1 - p)^{3}, \cdots $$

惊奇地发现它就是原来的柿子!

假设 $A = \sum\limits_{i = 1}^{+\infty}(1 - p)^{i - 1} \times i$,于是有:

$$ \dfrac{A - \sum\limits_{i = 1}^{+\infty}(1 - p)^{i - 1}}{1 - p} = A $$

用等比数列求和公式把柿子化成:

$$ \begin{aligned} \dfrac{A - \dfrac{1}{p}}{1 - p} &= A\\ A - \dfrac{1}{p} &= (1 - p)A\\ pA &= \dfrac{1}{p}\\ A &= \dfrac{1}{p^{2}}\\ \end{aligned} $$

(不会等比数列求和的可以去看百度百科。)

最后把原来提出去的 $p$ 乘回来就好,所以 $E(T)= \dfrac{1}{p}$。我认为这个东西可以当作结论来记,也不复杂。

  1. 利用整个过程的相似性(可以这么说吧)来「递归」计算。

假设我们第一次就拿到了想要的卡片,概率为 $p$。

如果没有拿到,那么概率为 $1 - p$。

如果正好是这 $1 - p$ 的概率,我们经过了这一步得到了什么呢?

什么也没得到,所以回到了起点。

回到了起点过后,我们什么也没改变,所以概率还是一样的,还是有 $p$ 的概率拿到想要的卡片,有 $1 - p$ 的概率再次回到起点。

所以就可以写出这么个柿子来:

$$ \begin{aligned} E(T) &= p + (1 - p)(E(T) + 1)\\ E(T) &= p + (1 - p)E(T) + 1 - p\\ pE(T) &= 1\\ E(T) &= \dfrac{1}{p}\\ \end{aligned} $$

好像很厉害的样子!

于是这个问题就得到了解决!

用一些小技巧可以把时间复杂度优化到 $\mathcal{O}(2^{n})$,不过好像没太大意义?

放个代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
double ans, p[25], sum[1 << 20];
int gsm(int x) {return x & 1 ? -1 : 1;}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    while(cin >> n) {
        for(int i = 1; i <= n; ++i) cin >> p[i];
        sum[0] = 0.0, ans = 0.0;
        for(int i = 1; i < (1 << n); ++i) {
            sum[i] = sum[i ^ (i & -i)] + p[__lg(i & -i) + 1];
            ans += gsm(__builtin_popcount(i) - 1) / sum[i];
        }
        cout << fixed << setprecision(4) << ans << '\n';
    }
    return 0;
}

[HAOI2015] 按位或

这两个东西其实差别不大,一样的套路转化一下问题就是基本一模一样的了。

但是你会发现在求 $E\big(\min(T)\big)$ 的时候,$T$ 的概率和 $p$ 并不好计算,这个时候就得用到高维前缀和/子集前缀和了(或者叫 SOSdp,$\texttt{Sum Over Subsets Dynamic Programming}$)。

这个东西暂时先不写,等我有空来了。

或者你硬是要用 FMT 或者 FWT 也行。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
double ans, p[25], sum[1 << 20];
int gsm(int x) {return x & 1 ? -1 : 1;}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n;
    for(int i = 0; i < (1 << n); ++i) {
        cin >> sum[i];
        for(int j = 0; j < n; ++j) {
            if((i >> j) & 1) p[j] += sum[i];
        }
    }
    for(int i = 0; i < n; ++i) {
        if(p[i] == 0.0) {
            cout << "INF";
            return 0;
        }
    }
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < (1 << n); ++j) {
            if((j >> i) & 1) {
                sum[j] += sum[j ^ (1 << i)];
            }
        }
    }
    for(int i = 1; i < (1 << n); ++i) {
        ans += gsm(__builtin_popcount(i) + 1) / (1 - sum[((1 << n) - 1) ^ i]);
    }
    cout << fixed << setprecision(10) << ans;
    return 0;
}
posted @ 2023-12-25 19:35  A_box_of_yogurt  阅读(2)  评论(0编辑  收藏  举报  来源
Document