codeforces 1556F - Sports Betting (概率dp)

题目链接:https://codeforces.com/contest/1556/problem/F

可以证明,一定存在胜利者,且胜利者们在同一个强连通分量中(反证法),所以考虑枚举胜利者

\(dp[winners]\) 表示胜利者为 \(winners\) 的概率,则期望为 \(\sum_{winners}dp[winners]\times|winners|\)

由胜利者都在同一个强连通分量中的性质可知,所有胜利者都可以击败每一个非胜利者,否则与强连通分量矛盾

那么计算 \(dp[winners]\) 可以考虑容斥,即枚举的 \(winners\) 可以击败所有非胜利者的情况中,减去胜利者为 \(winners\) 子集 \(sub\),同时 \(winners\sub\) 中的参赛者要击败所有其它参赛者的情况

时间复杂度 \(O(n^23^n)\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 17;
const int M = 1000000007;

int n;
int a[maxn], inv[2000010];
int dp[1<<maxn], w[maxn][maxn], in[maxn];

int qsm(int i, int po){
	int res = 1;
	while(po){
		if(po&1) res = 1ll * res * i % M;
		i = 1ll * i * i % M;
		po >>= 1;
	}
	return res;
}

int count(int s){
	int tmp = s;
	int cnt = 0;
	while(tmp){
		if(tmp & 1) ++cnt;
		tmp >>= 1;
	}
	return cnt;
}

int calc(int s){
	memset(in, 0, sizeof(in));
	for(int i = 0 ; i < n ; ++i){ if((s>>i) & 1) in[i] = 1; }
	
	int G = 1;
	for(int i = 0 ; i < n ; ++i) {
		if(!in[i]) continue;
		for(int j = 0 ; j < n ; ++j){
			if(in[j]) continue;
			G = 1ll * G * w[i][j] % M;
		}
	} 
	
	for(int s0 = s ; s0 ; s0 = (s0-1)&s){
		if(s == s0) continue;
		int g = 1;
		int r = (s^s0); 
		for(int i = 0 ; i < n ; ++i){
			if(!((r>>i)&1)) continue;
			for(int j = 0 ; j < n ; ++j){
				if(in[j]) continue;
				g = 1ll * g * w[i][j] % M;
			}
		}
		
		G = ((G - 1ll * dp[s0] * g % M) % M + M) % M;
	}
	dp[s] = G;
	
	return dp[s];
}

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	n = read();
	for(int i = 0 ; i < n ; ++i) a[i] = read();
	
	for(int i = 0 ; i < n ; ++i){
		for(int j = 0 ; j < n ; ++j){
			w[i][j] = 1ll * a[i] * qsm(a[i]+a[j], M-2) % M;
		}
	}
	
	int ans = 0;
	for(int i = 1 ; i < (1<<n) ; ++i){
		ans = (ans + 1ll * calc(i) * count(i) % M) % M;
	} 
	
	printf("%d\n", ans);
	
	return 0;
}
posted @ 2021-09-07 22:26  Tartarus_li  阅读(63)  评论(0编辑  收藏  举报