zoukankan      html  css  js  c++  java
  • 「THUWC 2017」随机二分图

    「THUWC 2017」随机二分图

    解题思路 :

    首先有一个 (40pts) 的做法:

    (20pts) 暴力枚举最终的匹配是怎样的,check一下计算方案数,后 (20pts)(f[s][i]) 表示当前左边的点匹配到前 (i) 个,右边的点匹配状况是 (s) 时继续往下匹配方案数的期望,枚举与 (i) 相连的边转移即可。

    对于剩下的 (t=1,t=2) 的情况,先和 (t = 0) 一样直接连 ((a1,b1), (a2,b2))。然后观察此时概率发生的偏差。

    (t=1) 为例,只选 ((a1,b1)) 或者只选 ((a2, b2)) 时概率和正确情况一样都是 (frac{1}{2}) 。但是如果两条边都选此时算的概率是 (frac{1}{4}) ,而应该是 (frac{1}{2}) ,所以还要补连一种转移同时选上四个点概率是 (frac{1}{4}) ,根据期望的线性性,正确性显然。

    对于 (t=2) 情况,和上面一样分析,发现对于同时选的情况多算了 (frac{1}{4}) ,补连一条概率是 (-frac{1}{4}) 的转移即可。

    此时我们就不能按照 (40pts) 的方法DP了,需要设 (f[s1][s2]) 表示此时左边点匹配状况是 (s1),右边匹配状况是 (s2) ,继续向下匹配方案数的期望。但是为了不重,我们每次还是要为 (s1) 中编号最小为匹配的点安排匹配,那么这样状态数就是和 (40pts) 的转移同阶的,用一个map记忆化一下复杂度就是 (O(n^22^n))

    code

    /*program by mangoyang*/
    #pragma GCC optimize("Ofast", "inline")
    #include<bits/stdc++.h>
    #define inf ((int)(1e9))
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    typedef long long ll;
    using namespace std;
    template <class T>
    inline void read(T &x){
        int f = 0, ch = 0; x = 0;
        for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
        for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
        if(f) x = -x;
    }
    const int INV2 = 500000004, INV4 = 250000002, mod = 1e9 + 7;
    map<int, int> f;
    int a[300], b[300], n, m, cnt;
    
    inline int Pow(int a, int b){
    	int ans = 1;
    	for(; b; b >>= 1, a = 1ll * a * a % mod)
    		if(b & 1) ans = 1ll * ans * a % mod;
    	return ans;
    }
    
    inline int dfs(int mask){
    	if(mask == (1 << (n << 1)) - 1) return 1;
    	if(f.count(mask)) return f[mask];
    	int now = 0, tmp = 0;
    	for(int i = n - 1; ~i; i--)
    		if(!((1 << i) & mask)) now = (1 << i);
    	for(int i = 1; i <= cnt; i++)
    		if((now & a[i]) && !(mask & a[i]))
    			(tmp += 1ll * dfs(mask | a[i]) * b[i] % mod) %= mod;
    	return f[mask] = tmp;
    }
    
    int main(){
    	read(n), read(m);
    	for(int i = 1, op, x, y; i <= m; i++){
    		read(op), read(x), read(y), x--, y--;
    		int tmp = (1 << x) | (1 << y + n);
    		a[++cnt] = tmp, b[cnt] = INV2;
    		if(op){
    			read(x), read(y), x--, y--;
    			a[++cnt] = (1 << x) | (1 << y + n), b[cnt] = INV2;
    			if(tmp & ((1 << x) | (1 << y + n))) continue;
    			tmp |= (1 << x) | (1 << y + n);
    			a[++cnt] = tmp, b[cnt] = op == 1 ? INV4 : -INV4 + mod;
    		}
    	}
    	cout << 1ll * dfs(0) * Pow(2, n) % mod << endl;
    	return 0;
    }
    
  • 相关阅读:
    【472】proceedings 改投 journals
    【471】Keras 深度神经网络实现
    iOS websocket接入的简单使用
    Windows下安装gazebo
    详解ROS文件系统
    /home/qian/anaconda3/lib/libpng16.so.16: undefined reference to `inflateValidate@ZLIB_1.2.9'
    /usr/lib/*** is not a symbolic link问题解决
    SC_leGO_LOAM安装使用
    3D激光slam开源框架汇总
    PCL——(10)PCL中使用随机采样一致性模型
  • 原文地址:https://www.cnblogs.com/mangoyang/p/10186853.html
Copyright © 2011-2022 走看看