分析

考虑状压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. 剑指Offer编程题(Java实现)——复杂链表的复制

    题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...

  2. MyEclipse img显示问题

    MyEclipse第一个例子,通过HTML的img显示图片,费两天的功夫,故作简单整理,图片2不显示根本原因还是src的路径不对. 选中project中的sr.jpg文件,运行查看浏览器显示的地址,此 ...

  3. 安装CentOS7虚拟机

    基础环境 Windows 10 VMware Workstation 1.下载CentOS7镜像 https://www.centos.org/download/ 此次安装使用的版本为: CentOS ...

  4. arm初识

    一.CPU从指令集角度分类 1.1. CISC  (X86) 1.1. 1. CISC CPU 指complex instruction set computer复杂指令集CPU 1.1.2. CIS ...

  5. Codeforces 1262F Wrong Answer on test 233(组合数)

    E1:设dp[i][j],表示在第i个位置的当前新状态超过原状态j分的方案数是dp[i][j],那么对于这种情况直接进行转移即可,如果a[i]==b[i]显然k种选择都可以,不影响j,如果不一样,这个 ...

  6. git命令?

    #文件及文件夹创建删除    mkdir  文件名称    (创建文件夹)    touch  文件名称    (创建文件)    rm -r  文件名称     (递归删除)    rm -rf 文 ...

  7. Linux安装Jenkins并部署springboot项目

    安装步骤: 1.跳转连接https://pkg.jenkins.io/redhat-stable/下载安装包 2.安装命令: sudo rpm -ih jenkins-2.73.2-1.1.noarc ...

  8. idea的使用技巧

    * 简介:程序员每日都会花费数小时使用ide编写和调试代码,其中很多操作都是机械重复且频率非常高,本着"工欲善其事必先利其器"的精神,闷头写代码之外花点时间研究一下自己用的ide, ...

  9. vb中的资源文件

    --- 一.VB中资源文件的分类 ---- 通常将资源分为两类:1.字符串资源,包括菜单和文本中使用的字符串,如"Hello World"等:2.二进制资源,如位图(.BMP),图 ...

  10. EffectiveC++01-03

    导读 作者Scott Meyers在如何有效运用C++方面给出了55个具体的做法,大致分为两类: 一般性的设计策略,集中于"如何在不同的做法中选择一种完成任务" 选择inherit ...