This is a harder version of the problem. In this version, \(n \le 7\).

Marek is working hard on creating strong test cases to his new algorithmic problem. Do you want to know what it is? Nah, we're not telling you. However, we can tell you how he generates test cases.

Marek chooses an integer \(n\) and \(n^2\) integers \(p_{ij}\) (\(1 \le i \le n\), \(1 \le j \le n\)). He then generates a random bipartite graph with \(2n\) vertices. There are \(n\) vertices on the left side: \(\ell_1, \ell_2, \dots, \ell_n\), and \(n\) vertices on the right side: \(r_1, r_2, \dots, r_n\). For each \(i\) and \(j\), he puts an edge between vertices \(\ell_i\) and \(r_j\) with probability \(p_{ij}\) percent.

It turns out that the tests will be strong only if a perfect matching exists in the generated graph. What is the probability that this will occur?

It can be shown that this value can be represented as \(\frac{P}{Q}\) where \(P\) and \(Q\) are coprime integers and \(Q \not\equiv 0 \pmod{10^9+7}\). Let \(Q^{-1}\) be an integer for which \(Q \cdot Q^{-1} \equiv 1 \pmod{10^9+7}\). Print the value of \(P \cdot Q^{-1}\) modulo \(10^9+7\).

\(n\le 7\),是一个很暴力的范围。

但是怎么暴力?

我们在搜索的过程中,如何很好的维护出最大匹配的信息?

考虑维护每一个左端点集合是否存在最大匹配,然后每次新增一个左端点,枚举这个点能到的集合,设为 \(s\),可以预处理出概率。然后再更新那些有最大匹配的概率。复杂度明显是爆的。

略微优化一下搜索过程,在搜索时处理出这个左端点如果连到了点 \(i\) 会有哪些最大匹配改变,可以用 __int128 状压,记为 \(f_i\)。然后枚举对应的集合时可以直接把所有 \(f_j(j\in s)\) 或起来就可以了。

可以考虑记忆化,用一个状压记录每个集合是否有最大匹配(状压的状压?有点绕)。然后就过了。记录的时候可以用一个 __int128 记到 map 里面,然后就可以过了。

#include<bits/stdc++.h>
using namespace std;
typedef unsigned __int128 LL;
const int N=10,P=1e9+7,S=1<<N;
int pown(int x,int y)
{
if(!y)
return 1;
int t=pown(x,y>>1);
if(y&1)
return 1LL*t*t%P*x%P;
return 1LL*t*t%P;
}
int n,p[N][N],f[N][S],cnt;
map<LL,int>mp[N];
LL mx;
void write(LL x)
{
if(!x)
return;
write(x/10);
putchar(x%10+48);
}
int dfs(int x,LL s)
{
/*printf("%d ",x),write(s);
puts("");*/
if(x==n)
{
return s==mx;
}
if(mp[x].find(s)!=mp[x].end())
return mp[x][s];
++cnt;
LL f[N];
for(int i=0;i<n;i++)
f[i]=0;
int ans=0;
for(int i=0;i<(1<<n);i++)
{
if(s>>i&1)
for(int k=0;k<n;k++)
f[k]|=((LL)1)<<(i|(1<<k));
}
for(int i=1;i<(1<<n);i++)
{
LL to=s;
for(int j=0;j<n;j++)
if(i>>j&1)
to|=f[j];
ans+=dfs(x+1,to)*1LL*::f[x][i]%P;
if(ans>=P)
ans-=P;
}
return mp[x][s]=ans;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<(1<<n);i++)
mx|=((LL)1)<<i;
int pw=pown(100,P-2);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",p[i]+j),p[i][j]=1LL*p[i][j]*pw%P;
for(int i=0;i<n;i++)
{
for(int j=0;j<(1<<n);j++)
{
f[i][j]=1;
for(int k=0;k<n;k++)
{
if(j>>k&1)
f[i][j]=1LL*f[i][j]*p[k][i]%P;
else
f[i][j]=1LL*f[i][j]*(1+P-p[k][i])%P;
}
}
}
printf("%d",dfs(0,1));
}

[CF1229E]Marek and Matching的更多相关文章

  1. Codeforces Round #588 (Div. 1) 简要题解

    1. 1229A Marcin and Training Camp 大意: 给定$n$个对$(a_i,b_i)$, 要求选出一个集合, 使得不存在一个元素好于集合中其他所有元素. 若$a_i$的二进制 ...

  2. 学习《Hardware-Efficient Bilateral Filtering for Stereo Matching》一文笔记。

    个人收藏了很多香港大学.香港科技大学以及香港中文大学里专门搞图像研究一些博士的个人网站,一般会不定期的浏览他们的作品,最近在看杨庆雄的网点时,发现他又写了一篇双边滤波的文章,并且配有源代码,于是下载下 ...

  3. LeetCode题解-----Wildcard Matching

    题目描述: '?' Matches any single character. '*' Matches any sequence of characters (including the empty ...

  4. cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'mvc:annotation-driven'.

    spring 配置文件报错报错信息:cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be ...

  5. [LeetCode] Wildcard Matching 外卡匹配

    Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. ...

  6. [LeetCode] Regular Expression Matching 正则表达式匹配

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

  7. Beginning Scala study note(5) Pattern Matching

    The basic functional cornerstones of Scala: immutable data types, passing of functions as parameters ...

  8. ios 关于问题 no matching provisioning profiles found

    ios 关于问题 no matching provisioning profiles found

  9. iOS 苹果开发证书失效的解决方案(Failed to locate or generate matching signing assets)

    从2月14日开始,上传程序的同学可能会遇到提示上传失败的提示. 并且打开自己的钥匙串,发现所有的证书全部都显示此证书签发者无效. 出现以下情况: Failed to locate or generat ...

  10. ORA-12516:TNS:listener could not find available handler with matching protocol stack

    应用程序连接测试数据库时报ORA-12516:TNS:listener could not find available handler with matching protocol stack 检查 ...

随机推荐

  1. 使用kube-bench检测Kubernetes集群安全

    目录 一.系统环境 二.前言 三.CIS (Center for Internet Security)简介 四.什么是Kube-Bench? 五.使用kube-bench检测不安全的设置 5.1 手动 ...

  2. 02.中台框架前台项目 admin.ui.plus 学习-介绍与简单使用

    中台框架前台项目 admin.ui.plus 的初识 基于 vue3.x + CompositionAPI setup 语法糖 + typescript + vite + element plus + ...

  3. 《Linux基础》03. 运行级别 · 实用指令

    @ 目录 1:运行级别 2:帮助指令 2.1:man 2.2:help 3:文件目录指令 3.1:pwd 3.2:ls 3.3:cd 3.4:mkdir 3.5:rmdir 3.6:touch 3.7 ...

  4. LSTM推导

    LSTM推导 forward propagation def lstm_cell_forward(xt, a_prev, c_prev, parameters): """ ...

  5. nvm、node、vue安装、vue项目创建打包

    nvm.node.vue安装.创建vue项目 nvm作用:可以管理多个版本的node,切换node版本,下载node. 前情提要 参 考:https://zhuanlan.zhihu.com/p/51 ...

  6. .NET周刊【9月第4期 2023-09-24】

    国内文章 有趣的"可扩展近似计数"算法 https://zhuanlan.zhihu.com/p/656817283 在编程的世界里看见数学的身影,会让我充满好奇和兴奋.这不,在一 ...

  7. Go语言系列——11-数组和切片、12-可变参数函数、13-Maps、14-字符串、15-指针、16-结构体、17-方法、18-接口(一)、19-接口(二)、19-自定义集合类型、20-并发入门

    文章目录 11-数组和切片 数组 数组的声明 数组是值类型 数组的长度 使用 range 迭代数组 多维数组 切片 创建一个切片 切片的修改 切片的长度和容量 使用 make 创建一个切片 追加切片元 ...

  8. How can I access GPT-4?

    How can I access GPT-4?   Written by Joshua J.. Updated over a week ago API Access Most users will n ...

  9. 【技术积累】《MongoDB实战》笔记(1)

    <MongoDB实战>笔记 第一章 为现代Web而生的数据库 特性 mongodb适合做水平扩展的数据库. mongodb把文档组织成集合,无schema. 索引 mongodb的二级索引 ...

  10. mysql之简单的多表查询

    最简单的多表查询需要用到连操作符(join) 1.笛卡儿积 形式为table1 join table2.如: select e.fname,e.lname,d.name from employee e ...