我是靠谱客的博主 背后星月,最近开发中收集的这篇文章主要介绍[学习笔记] min-max容斥,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

结论及证明

给定集合 S S S m a x ( S ) max(S) max(S)为集合 S S S中的最大值, m i n ( S ) min(S) min(S)为集合 S S S中的最小值,则我们有一个式子:
m a x ( S ) = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − 1 × m i n ( T ) max(S)=sum_{Tsubseteq S}(-1)^{|T|-1}times min(T) max(S)=TS(1)T1×min(T)不多说,直接开证( ),首先我们设一个容斥系数 f ( ∣ T ∣ ) f(|T|) f(T)使这个式子成立:
m a x ( S ) = ∑ T ⊆ S f ( ∣ T ∣ ) × m i n ( T ) max(S)=sum_{Tsubseteq S}f(|T|)times min(T) max(S)=TSf(T)×min(T)我们考虑 x + 1 x+1 x+1大的元素会被算多少次(也就是它作为最小值出现的时候),枚举 [ 1 , x ] [1,x] [1,x]大怎么选:
∑ i = 0 x C ( x , i ) × f ( i + 1 ) sum_{i=0}^x C(x,i)times f(i+1) i=0xC(x,i)×f(i+1)然后这个式子必须满足 x = 0 x=0 x=0时为 1 1 1,其他时候为 0 0 0
[ x = = 0 ] = ∑ i = 0 x C ( x , i ) × f ( i + 1 ) [x==0]=sum_{i=0}^x C(x,i)times f(i+1) [x==0]=i=0xC(x,i)×f(i+1)你可以发现这是一个二项式反演的这个形式:
f ( n ) = ∑ i = 0 n C ( n , i ) × g ( i ) ⇒ g ( n ) = ∑ i = 0 n ( − 1 ) n − i C ( n , i ) × f ( i ) f(n)=sum_{i=0}^nC(n,i)times g(i)Rightarrow g(n)=sum_{i=0}^n(-1)^{n-i}C(n,i)times f(i) f(n)=i=0nC(n,i)×g(i)g(n)=i=0n(1)niC(n,i)×f(i)(如果你觉得系数对不上,你可以先把 f ( i + 1 ) f(i+1) f(i+1)整体左移,套公式后再右移回来)那么:
f ( x + 1 ) = ∑ i = 0 x ( − 1 ) x − i C ( x , i ) × [ x = = 0 ] f(x+1)=sum_{i=0}^x(-1)^{x-i}C(x,i)times [x==0] f(x+1)=i=0x(1)xiC(x,i)×[x==0] f ( x + 1 ) = ( − 1 ) x f(x+1)=(-1)^x f(x+1)=(1)x f ( x ) = ( − 1 ) x − 1 f(x)=(-1)^{x-1} f(x)=(1)x1兄弟们,得证了!!!淦!!!

kth-minmax 反演

后来推了一下,和上面方法一样。

哥哥现在来推一下 k t h − m i n m a x tt kth-minmax kthminmax 反演:

k t h m a x ( S ) = ∑ ∣ T ∣ ≥ k ( − 1 ) ∣ T ∣ − k ( ∣ T ∣ − 1 k − 1 ) min ⁡ ( T ) kthmax(S)=sum_{|T|geq k}(-1)^{|T|-k}{|T|-1choose k-1}min(T) kthmax(S)=Tk(1)Tk(k1T1)min(T)

假设不知道这东西,我们设容斥系数为 f ( ∣ T ∣ ) f(|T|) f(T)

k t h m a x ( S ) = ∑ ∣ T ∣ ≥ k f ( ∣ T ∣ ) min ⁡ ( T ) kthmax(S)=sum_{|T|geq k}f(|T|)min(T) kthmax(S)=Tkf(T)min(T)

考虑第 x + 1 x+1 x+1 大的元素会被计算多少次(作为最小值):

∑ i = k − 1 x C ( x , i ) × f ( i + 1 ) sum_{i=k-1}^xC(x,i)times f(i+1) i=k1xC(x,i)×f(i+1)

这个柿子必须满足 x = k − 1 x=k-1 x=k1 的时候为 1 1 1,其他时候为 0 0 0

[ x = k − 1 ] = ∑ i = k − 1 x C ( x , i ) × f ( i + 1 ) [x=k-1]=sum_{i=k-1}^{x}C(x,i)times f(i+1) [x=k1]=i=k1xC(x,i)×f(i+1)

先平移一下 f f f,令 g ( x ) = [ x = k − 1 ] , f ′ ( x ) = f ( x + 1 ) g(x)=[x=k-1],f'(x)=f(x+1) g(x)=[x=k1],f(x)=f(x+1),如果 x < k − 1 x<k-1 x<k1 就把 f ′ ( x ) f'(x) f(x) 设置为 0 0 0

g ( x ) = ∑ i = 0 x C ( x , i ) × f ′ ( i ) g(x)=sum_{i=0}^xC(x,i)times f'(i) g(x)=i=0xC(x,i)×f(i)

我直接一波二项式反演:

f ′ ( x ) = ∑ i = 0 x ( − 1 ) x − i ⋅ ( x i ) ⋅ g ( i ) = ∑ i = 0 x ( − 1 ) x − i ⋅ ( x i ) ⋅ [ i = k − 1 ] f'(x)=sum_{i=0}^x (-1)^{x-i}cdot {xchoose i}cdot g(i)=sum_{i=0}^x (-1)^{x-i}cdot {xchoose i}cdot [i=k-1] f(x)=i=0x(1)xi(ix)g(i)=i=0x(1)xi(ix)[i=k1]

f ′ ( x ) = ( − 1 ) x − k + 1 ⋅ ( x k − 1 ) f'(x)=(-1)^{x-k+1}cdot {xchoose k-1} f(x)=(1)xk+1(k1x)

f ( x ) = ( − 1 ) x − k ⋅ ( x − 1 k − 1 ) f(x)=(-1)^{x-k}cdot{x-1choose k-1} f(x)=(1)xk(k1x1)

例题

Card Collector

n n n张卡片,每一次你有 p i p_i pi的概率买到第 i i i张卡。求买到所有卡的期望购买次数。
n ≤ 20 , ∑ p i ≤ 1 nleq20,sum p_ileq1 n20,pi1

m a x ( S ) max(S) max(S)表示组成 S S S的最后一个元素的出现时间, m i n ( S ) min(S) min(S)表示组成 S S S的第一个元素的出现时间:
m a x ( U ) = ∑ S ⊆ U ( − 1 ) ∣ S ∣ − 1 × m i n ( S ) max(U)=sum_{Ssubseteq U}(-1)^{|S|-1}times min(S) max(U)=SU(1)S1×min(S)然后 m i n ( S ) min(S) min(S)很容易算:
m i n ( S ) = 1 ∑ i ∈ S p [ i ] min(S)=frac{1}{sum_{iin S}p[i]} min(S)=iSp[i]1

#include <cstdio>
#define db double
const int M = 1<<20;
int read()
{
    int num=0,flag=1;char c;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    while(c>='0'&&c<='9')num=(num<<3)+(num<<1)+(c^48),c=getchar();
    return num*flag;
}
int n,m,bit[M];db ans,p[20];
signed main()
{
	while(~scanf("%d",&n))
	{
		ans=0;m=1<<n;
		for(int i=0;i<n;i++)
			scanf("%lf",&p[i]);
		for(int i=1;i<m;i++)
			bit[i]=bit[i>>1]+(i&1);
		for(int i=1;i<m;i++)
		{
			db s=0;int f=(bit[i]&1)?1:-1;
			for(int j=0;j<n;j++)
				if((1<<j)&i) s+=p[j];
			ans=(ans+f*(1/s));
		}
		printf("%lfn",ans);
	}
}

按位或

https://blog.csdn.net/C202044zxy/article/details/106734521

wait

https://blog.csdn.net/C202044zxy/article/details/97758036

总结

发现很多关于首次达到某个条件的时间(期望次数)的题都可以用 m i n − m a x tt min-max minmax反演做,重要的是把时间作为大小比较的关键字来定义出状态,通常最小不好求但是最大好求(或者反之)

最后

以上就是背后星月为你收集整理的[学习笔记] min-max容斥的全部内容,希望文章能够帮你解决[学习笔记] min-max容斥所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部