分析

考虑状压DP,令\(f[sta]\)表示已匹配状态是\(sta\)(\(0\)代表已匹配)时完美匹配的期望数量,显然\(f[0]=1\)。

一条边出现了不代表它一定在完美匹配内,这也导致很难去直接利用题目中的边组来解决问题。

对于第二类边组,如果把两条边分开考虑(可以理解为把一个第二类的边组看成两个第一类的边组)。如果只有一条边出现在了完美匹配中,此时的贡献是\(50\%\),显然是正确的。如果两条边都出现在了完美匹配中,此时的贡献是\(50\% \times 50\% = 25\%\),但是根据第二类边组的定义,两条边都出现在完美匹配中的贡献应该也是\(50\%\)。所以我们可以再添加一个只包含一条边的边组,这里面的边比较特殊,其连接了这个第二类边组的四个结点,出现概率为\(25\%\),来补充不足的贡献。

第三类边组的处理方法类似,添加一个只包含一条边的边组,边连接了四个结点,出现概率为\(-25\%\),来消去多余的贡献。

为了减小时间复杂度,每次转移时要确保能把最高位的\(1\)异或掉。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <map>
#define rin(i,a,b) for(int i=(a);i<=(b);i++)
#define rec(i,a,b) for(int i=(a);i>=(b);i--)
#define trav(i,a) for(int i=head[(a)];i;i=e[i].nxt)
typedef long long LL;
using std::cin;
using std::cout;
using std::endl; inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
} const LL MOD=1e9+7,INV2=5e8+4,INV4=2.5e8+2;
int n,m,cnt,a[505];
LL p[505];
std::map<int,LL> mp; LL dfs(int sta){
if(!sta) return 1;
if(mp.find(sta)!=mp.end()) return mp[sta];
LL ret=0;
rin(i,1,cnt){
if((sta|a[i])==sta&&(a[i]<<1)>sta)
ret=(ret+dfs(sta^a[i])*p[i])%MOD;
}
return mp[sta]=ret;
} int main(){
n=read(),m=read();
rin(i,1,m){
int typ=read();
if(typ==0){
int x=read(),y=read();
a[++cnt]=((1<<(x-1))|(1<<(y+n-1)));
p[cnt]=INV2;
}
else if(typ==1){
int x1=read(),y1=read(),x2=read(),y2=read();
int temp1=((1<<(x1-1))|(1<<(y1+n-1))),temp2=((1<<(x2-1))|(1<<(y2+n-1)));
a[++cnt]=temp1,p[cnt]=INV2;
a[++cnt]=temp2,p[cnt]=INV2;
if(!(temp1&temp2)) a[++cnt]=(temp1|temp2),p[cnt]=INV4;
}
else{
int x1=read(),y1=read(),x2=read(),y2=read();
int temp1=((1<<(x1-1))|(1<<(y1+n-1))),temp2=((1<<(x2-1))|(1<<(y2+n-1)));
a[++cnt]=temp1,p[cnt]=INV2;
a[++cnt]=temp2,p[cnt]=INV2;
if(!(temp1&temp2)) a[++cnt]=(temp1|temp2),p[cnt]=MOD-INV4;
}
}
mp.clear();
printf("%lld\n",(1<<n)*dfs((1<<(n<<1))-1)%MOD);
return 0;
}

[思路题][LOJ2290][THUWC2017]随机二分图:状压DP+期望DP的更多相关文章

  1. P4547 [THUWC2017]随机二分图(状压,期望DP)

    期望好题. 发现 \(n\) 非常小,应该要想到状压的. 我们可以先只考虑 0 操作. 最难的还是状态: 我们用 \(S\) 表示左部点有哪些点已经有对应点, \(T\) 表示右部点有哪些点已经有对应 ...

  2. 洛谷 P4547 & bzoj 5006 随机二分图 —— 状压DP+期望

    题目:https://www.luogu.org/problemnew/show/P4547 https://www.lydsy.com/JudgeOnline/problem.php?id=5006 ...

  3. [LOJ2290] [THUWC2017] 随机二分图

    题目链接 LOJ:https://loj.ac/problem/2290 洛谷:https://www.luogu.org/problemnew/show/P4547 Solution 首先考虑只有第 ...

  4. Luogu4547 THUWC2017 随机二分图 概率、状压DP

    传送门 考虑如果只有$0$组边要怎么做.因为$N \leq 15$,考虑状压$DP$.设$f_i$表示当前的匹配情况为$i$时的概率($i$中$2^0$到$2^{N-1}$表示左半边的匹配情况,$2^ ...

  5. [BZOJ5006][LOJ#2290][THUWC2017]随机二分图(概率+状压DP)

    https://loj.ac/problem/2290 题解:https://blog.csdn.net/Vectorxj/article/details/78905660 不是很好理解,对于边(x1 ...

  6. THUWC2017随机二分图

    题面链接 洛谷 sol 唯一的重点是拆边... 0的不管,只看1.2. 先无论如何把两条边的边权赋为\(0.5\)然后我们发现如果两个都选了. 对于第一种边,我们发现如果\(\frac{1}{2} * ...

  7. 51nod 马拉松30 C(构二分图+状压dp)

    题意 分析 考虑一个图能被若干简单环覆盖,那么一定是每个点恰好一个出度,恰好一个出度 于是类似最小路径覆盖的处理,我们可以把每个点拆成2个点i和i',如果有一条边(i,j),那么将i和j'连起来 那么 ...

  8. 题解 洛谷 P4547 【[THUWC2017]随机二分图】

    根据题意,题目中所求的即为所有\(n!\)种完美匹配的各自的出现概率之和再乘上\(2^n\)的值. 发现\(n\)很小,考虑状压\(DP\).设\(f_{S,T}\)为左部图匹配情况为\(S\),右部 ...

  9. 【洛谷3343_BZOJ3925】[ZJOI2015]地震后的幻想乡(状压 DP_期望)

    题目: 洛谷 3343 BZOJ 3925 分析: 谁给我说这是个期望概率神题的,明明没太大关系好吧 「提示」里那个结论哪天想起来再问 Jumpmelon 怎么证. 首先,由于开始修路前 \(e_i\ ...

随机推荐

  1. 【Linux开发】OpenCV在ARM-linux上的移植过程遇到的问题2---CMAKE配置问题

    实际上这里说的是移植的第一步,下载到源码后,我用的是opencv2.4.9,解压缩,然后可以利用cmake-gui来进行configure配置,这里面需要设置交叉编译的工具链,具体的可以参考[Linu ...

  2. 【Qt开发】foreach用法

    If you just want to iterate over all the items in a container in order, you can use Qt's foreach key ...

  3. selenium学习-对当前浏览器窗口截屏

    方法:get_screenshot_as_file(filename) # coding=UTF-8 #16.对当前浏览器窗口截屏 import sys reload(sys) sys.setdefa ...

  4. 多线程14-Barrier

    , b => Console.WriteLine());         ; i <= ; i++)             {                 Console.Write ...

  5. A+B and A*B problem 大数相加 相乘 模拟

    A+B and A*B problem 大数相加 相乘 模拟 题意 给你两个数a和b,这两个数很大,然后输出这两个数相加的和,相乘的积. 解题思路 模拟,但是还是搜了搜代码实现,发现这个大佬写的是真的 ...

  6. [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增)

    [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增) 题面 n个点的图,点i和[l[i],i)的所有点连双向边.每次询问(l,r,x)表示x到[l,r]的所有点的最短 ...

  7. python列表的复制,扯一下浅拷贝与深拷贝的区别

    将一个列表的数据复制到另一个列表中.使用列表[:],可以调用copy模块 import copy A = [21,22,23,24,['a','b','c','d'],25,26] B = A #直接 ...

  8. 五、JVM — 类加载器

    回顾一下类加载过程 类加载器总结 双亲委派模型 双亲委派模型介绍 双亲委派模型实现源码分析 双亲委派模型的好处 如果我们不想要双亲委派模型怎么办? 自定义类加载器 推荐 回顾一下类加载过程 类加载过程 ...

  9. Kibana 基本操作

    es中的索引对应mysql的数据库.类型对应mysql的表.文档对应mysql的记录.映射对应mysql的索引索引:index类型:type映射:mappings 1.创建索引在kibana的Dev ...

  10. 什么情况下会出现undefined

    1.函数定义形参不传值,2.预解释,只声明不定义时输出变量3.对象取属性值,属性值不存在