「THUWC 2017」随机二分图(状压DP)(概率DP)

传送门

首先有 40 p t s 40pts 暴力就是枚举排列算概率,还有就是直接状压 f [ i ] [ S ] f[i][S] 表示左边选到 i i 右边集合为 S S 的概率

想一想,最后求的是什么,就是我们钦定一些边必须选使得有完美匹配,然后将这些边一起出现的概率乘起来作为贡献

把 1 类边和 2 类边都拆成 0 类边

考虑若最后钦定的边中 1 类的两条同时出现,那么它们两个的贡献是 1 / 4 1/4 ,而本应该是 1 / 2 1/2 ,所以我们添加一个两条边出现概率为 1 / 4 1/4 的捆绑来平衡概率

如果这两条边在某一次钦定中同时存在了,那么我们的捆绑肯定也会在某一次钦定中存在

如果钦定的边中只有其中 1 条,那么它对概率的贡献是 1 / 2 1/2 ,本身就是 1 / 2 1/2

于是乎概率就正确了, 2 类边添加概率为 1 / 4 -1/4 的捆绑即可

发现这样并不能刚刚那样状压

我们令 f [ S 1 ] [ S 2 ] f[S_1][S_2] 为两边集合为 S 1 , S 2 S_1,S_2 的概率,每次枚举最小的不在 S 1 S_1 中的转移即可,复杂度 O ( n 2 2 n ) O(n^22^n)

感觉拆边新增一个捆绑边来平衡概率挺巧妙的
另外了解了枚举最小不在集合中的点来转移的方法

扫描二维码关注公众号,回复: 8675838 查看本文章
#include<bits/stdc++.h>
#define cs const
using namespace std;
cs int N = 16, M = N*N*3;
cs int Mod = 1e9 + 7, inv2 = (Mod+1)>>1, inv4 = (Mod+1)>>2;
int read(){
	int cnt = 0, f = 1; char ch = 0;
	while(!isdigit(ch)){ ch = getchar(); if(ch == '-') f = -1; }
	while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();
	return cnt * f;
}
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
void Add(int &a, int b){ a = add(a, b); }
int ksm(int a, int b){int ans=1; for(;b;b>>=1,a=mul(a,a)) if(b&1) ans=mul(ans,a); return ans;}
int n, m, a[M], b[M], ct, all;
unordered_map<int, int> f;
int dp(int S){
	if(S == all) return 1;
	if(f.count(S)) return f[S];
	int nxt = -1;
	for(int i = 0; i < n; i++) if(!(S & (1<<i))){ nxt = 1<<i; break; }
	int ret = 0;
	for(int i = 1; i <= ct; i++)
		if((nxt & a[i]) && !(S & a[i]))
			Add(ret, mul(b[i], dp(S | a[i])));
	return f[S] = ret;
}
int main(){
	n = read(), m = read(); all = (1<<n+n) - 1;
	for(int i = 1; i <= m; i++){
		int op = read(), x = read()-1, y = read()-1, S = 0;
		a[++ct] = S = (1<<x)|(1<<(y+n)); b[ct] = inv2;
		if(op){
			x = read()-1, y = read()-1; 
			a[++ct] = (1<<x)|(1<<(y+n)); b[ct] = inv2;
			if(S & ((1<<x)|(1<<y+n))) continue;
			a[++ct] = S | ((1<<x)|(1<<y+n)); b[ct] = op == 1 ? inv4 : Mod-inv4;
		}
	} cout << mul(dp(0), ksm(2,n)); return 0;
}
发布了610 篇原创文章 · 获赞 94 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/sslz_fsy/article/details/103497864