洛谷 P3343 - [ZJOI2015]地震后的幻想乡(朴素状压 DP/状压 DP+微积分)
鸽子 tzc 竟然来补题解了,奇迹奇迹(
神仙题 %%%%%%%%%%%%
解法 1:
首先一件很明显的事情是这个最小值可以通过类似 Kruskal 求最小生成树的方法求得。我们将所有边按边权从小到大排序并依次加入图中,如果加入边权为 \(v\) 的边后图首次连通,那么这张图对答案的贡献就是 \(v\)。
那么怎么求这个期望值呢?我们考虑枚举加入多少条边后图首次连通,记这个数为 \(c\),那么这种情况对期望的贡献就是 \(\dfrac{c}{m+1}\),如果我们能再求出 \(p_c\) 表示加入 \(c\) 条边后图首次连通的概率,那么即可通过 \(ans=\sum\limits_{i=1}^mp_i\dfrac{i}{m+1}\) 求出答案。
因此现在问题就转化为如何求 \(p_i\),注意到此题 \(n\) 很小,因此考虑状压 \(dp\),我们设 \(f_{S,i}\) 表示在点 \(S\) 中的点之间连 \(i\) 条边后 \(S\) 中的点不连通的方案数,再设 \(g_{S,i}\) 表示在 \(S\) 中的点之间连 \(i\) 条边后 \(S\) 的点不连通的方案数。转移还是相对来说比较容易,我们先预处理出 \(D_S\) 表示 \(S\) 中的点之间总共连出了多少条边。对于 \(f\) 的转移,我们记 \(x\) 为 \(S\) 中最小的元素,即代码实现中的 s&-s,我们枚举哪些点与 \(x\) 在同一个连通块中,记作 \(T\),再枚举 \(T\) 中的点连了多少条边,那么有 \(f_{S,i}=\sum\limits_{x\in T\subsetneq S}\sum\limits_{j=0}^ig_{T,i}\dbinom{D_{S-T}}{i-j}\)。至于 \(g\) 的转移,显然满足 \(f_{S,i}+g_{S,i}=\dbinom{d_S}{i}\),因为在 \(S\) 中的边选 \(i\) 条边总共只有 \(\dbinom{d_S}{i}\) 种选择。子集枚举转移一下即可,复杂度 \(3^nm^2\)
接下来考虑知道 \(f,g\) 后怎样求出 \(p\),记 \(U=\{1,2,3,\cdots,n\}\),那么 \(p_i\) 显然等于加入 \(i-1\) 条边后不连通的概率减去加入 \(i\) 条边后不连通的概率。而显然加入 \(i\) 条边后不连通的概率显然为 \(\dfrac{f_{U,i}}{\dbinom{m}{i}}\),因此 \(p_i=\dfrac{f_{U,i-1}}{\dbinom{m}{i-1}}-\dfrac{f_{U,i}}{\dbinom{m}{i}}\),代入上面的式子求一下即可。
const int MAXN=10;
const int MAXP=1<<10;
const int MAXM=45;
int n,m,ed[MAXN+5][MAXN+5],d[MAXP+5];
double c[MAXM+5][MAXM+5],f[MAXP+5][MAXM+5],g[MAXP+5][MAXM+5];
int main(){
scanf("%d%d",&n,&m);
for(int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),ed[u][v]++;
for(int i=0;i<(1<<n);i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++)
if((i>>j-1&1)&&(i>>k-1&1)) d[i]+=ed[j][k];
for(int i=0;i<=MAXM;i++){
c[i][0]=1;
for(int j=1;j<=i;j++) c[i][j]=c[i-1][j]+c[i-1][j-1];
}
for(int i=0;i<(1<<n);i++){
for(int j=0;j<=d[i];j++){
for(int k=i;k;k=(k-1)&i){
if(k&(i&-i)){
for(int l=0;l<=min(d[k],j);l++){
f[i][j]+=g[k][l]*c[d[i^k]][j-l];
}
}
} g[i][j]=c[d[i]][j]-f[i][j];
}
} double ans=0;
for(int i=0;i<=m;i++) ans+=1.0/(m+1)*f[(1<<n)-1][i]/c[m][i];
printf("%.6lf\n",ans);
return 0;
}
解法 2:
此题也可以从积分的角度来理解。
u1s1 这个做法就比上面那个做法不知道神仙多少倍了。
注意到此题涉及连续型变量,因此可以采用微积分,我们记 \(p(t)\) 为将所有边边权从小到大排序后,加入边权为 \(t\) 的边后图首次连通的概率,那么有
ans&=\int_0^1p(x)x\,\mathrm dx\\
&=\int_0^1p(x)\int_0^x\,\mathrm dz\,\mathrm dx\\
&=\int_0^1\int_z^1p(x)\,\mathrm dx\,\mathrm dz
\end{aligned}
\]
如果我们记 \(q(x)\) 为 \(\int_x^1p(z)\,\mathrm dz\),即 \(x\) 时刻图不连通的概率,那么
\]
接下来考虑怎样求这个东西,我们再定义二元函数 \(f(S,t)\) 表示在 \(t\) 时刻 \(S\) 中的点不连通的概率,转移就套路记 \(x\) 为 \(S\) 中最小的元素,并套路地枚举 \(t\) 时刻与 \(x\) 在同一连通块中的点 \(T\),那么显然 \(S-T,T\) 之间所有边的边权都要 \(>t\),我们记这样边的个数为 \(c(S-T,T)\),那么:
\]
但是显然这个 \(f(S,t)\) 不能直接通过类似 DP 的方式求出来,因为它涉及连续变量 \(t\),注意到答案是一个积分形式,因此考虑将 DP 状态也设成一个积分的形式,我们从答案出发,答案要求
\]
即
\]
其中 \(U=\{1,2,3,\cdots,n\}\)。
因此考虑设 \(dp_S=\int_0^1f(S,t)\,\mathrm dt\)。
不过这样一来就有一个问题,在 \(f(S,t)\) 的转移式子中转移出来的不再是 \(\int_0^1f(T,t)\,\mathrm dt\),而是 \(\int_0^1f(T,t)(1-t)^{k}\,\mathrm dt\) 的形式。因此考虑将原来一维 DP 状态扩展到二维,即设 \(dp_{S,k}=\int_0^1f(S,t)(1-t)^k\,\mathrm dt\),那么有如下转移:
dp_{S,k}&=\int_0^1f(S,t)(1-t)^k\,\mathrm dt\\
&=\int_0^1\sum\limits_{x\in T\subsetneq S}(1-f(T,t))(1-t)^{c(S-T,T)}·(1-t)^k\,\mathrm dt\\
&=\int_0^1\sum\limits_{x\in T\subsetneq S}((1-t)^{c(S-T,T)+k}-f(T,t)(1-t)^{c(S-T,T)+k})\,\mathrm dt\\
&=\sum\limits_{x\in T\subsetneq S}\int_0^1(1-t)^{c(S-T,T)+k}\,\mathrm dt-\int_0^1f(T,t)(1-t)^{c(S-T,T)+k}\,\mathrm dt\\
\end{aligned}
\]
注意到左边的东西可以转化为
\]
这显然就是一个幂函数的积分,记 \(F(x)=\int_0^xt^{c(S-T,T)+k}\,\mathrm dt\),那么 \(F(x)=\dfrac{x^{c(S-T,T)+k+1}}{c(S-T,T)+k+1}\)
将 \(x=1\) 代入得原式 \(=\dfrac{1}{c(S-T,T)+k+1}\)
再看右边,这显然可以通过前面的 DP 状态推出来,这玩意儿显然就等于 \(dp_{T,c(S-T,T)+k}\)
故 \(dp_{S,k}=\dfrac{1}{c(S-T,T)+k+1}-dp_{T,c(S-T,T)+k}\),简单递推求一下,最终答案即为 \(dp_{U,0}\)
时间复杂度 \(3^nm\),比上面的解法少一个 \(m\)。
const int MAXN=10;
const int MAXM=45;
const int MAXP=1<<10;
int n,m,con[MAXN+5];
double f[MAXP+5][MAXM+5];
int main(){
scanf("%d%d",&n,&m);
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);
con[u]|=(1<<v-1);con[v]|=(1<<u-1);
}
for(int i=1;i<(1<<n);i++) if(i&1){
for(int j=i;j;j=(j-1)&i) if((j^i)&&(j&1)){
int cnt=0;
for(int k=1;k<=n;k++) if((i>>(k-1)&1)&&(~j>>(k-1)&1)) cnt+=__builtin_popcount(con[k]&j);
for(int k=0;k+cnt<=m;k++) f[i][k]+=1.0/(1+k+cnt)-f[j][k+cnt];
}
} printf("%.6lf\n",f[(1<<n)-1][0]);
return 0;
}
洛谷 P3343 - [ZJOI2015]地震后的幻想乡(朴素状压 DP/状压 DP+微积分)的更多相关文章
- [bzoj3925] [洛谷P3343] [ZJOI2015] 地震后的幻想乡
Description 傲娇少女幽香是一个很萌很萌的妹子,而且她非常非常地有爱心,很喜欢为幻想乡的人们做一些自己力所能及的事情来帮助他们. 这不,幻想乡突然发生了地震,所有的道路都崩塌了.现在的首要任 ...
- 洛谷P3343 [ZJOI2015]地震后的幻想乡 [DP,概率期望]
传送门 思路 题目给了一个提示:对于\(n\)个\([0,1]\)的随机变量,其中第\(k\)小的期望大小是\(\frac{k}{n+1}\). 这引导我们枚举边的相对大小的全排列,然后求最小生成树 ...
- 洛谷3343(ZJOI2015)地震后的幻想乡
题目:https://www.luogu.org/problemnew/show/P3343 1.那个时间与边的大小排名有关,所以需要求一下最大边的期望排名就行. 2.期望排名是这样算的:(排名为1的 ...
- P3343 [ZJOI2015]地震后的幻想乡
传送门 给积分大佬跪了 再给状压大佬也跪了 //minamoto #include<bits/stdc++.h> #define rint register int #define ll ...
- 【BZOJ3925】[ZJOI2015]地震后的幻想乡(动态规划)
[BZOJ3925][ZJOI2015]地震后的幻想乡(动态规划) 题面 BZOJ 洛谷 题解 题目里面有一句提示:对于\(n\)个\([0,1]\)之间的随机变量\(x1,x2,...,xn\),第 ...
- 【洛谷3343_BZOJ3925】[ZJOI2015]地震后的幻想乡(状压 DP_期望)
题目: 洛谷 3343 BZOJ 3925 分析: 谁给我说这是个期望概率神题的,明明没太大关系好吧 「提示」里那个结论哪天想起来再问 Jumpmelon 怎么证. 首先,由于开始修路前 \(e_i\ ...
- 题解-ZJOI2015地震后的幻想乡
Problem bzoj & 洛谷 题意简述:给定一个\(n\)(\(n\leq 10\))个点\(m\)条边的无向图,每条边的权值为一个\(0\)到\(1\)之间的连续随机变量,求图的最小生 ...
- BZOJ3925: [Zjoi2015]地震后的幻想乡
Description 傲娇少女幽香是一个很萌很萌的妹子,而且她非常非常地有爱心,很喜欢为幻想乡的人们做一些自己力所能及的事情来帮助他们. 这不,幻想乡突然发生了地震,所有的道路都崩塌了.现在的首要任 ...
- [ZJOI2015]地震后的幻想乡(期望+dp)
题目描述 傲娇少女幽香是一个很萌很萌的妹子,而且她非常非常地有爱心,很喜欢为幻想乡的人们做一些自己力所能及的事情来帮助他们. 这不,幻想乡突然发生了地震,所有的道路都崩塌了.现在的首要任务是尽快让幻想 ...
随机推荐
- Hive架构及搭建方式
目录 前言 hive的基础知识 基本架构 metastore 内嵌服务和数据库 内嵌服务 服务和数据库单独部署 hcatalog 客户端 客户端的本地模式 beeline beeline的自动模式 j ...
- 【数据结构与算法Python版学习笔记】树——树的遍历 Tree Traversals
遍历方式 前序遍历 在前序遍历中,先访问根节点,然后递归地前序遍历左子树,最后递归地前序遍历右子树. 中序遍历 在中序遍历中,先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树. 后序遍 ...
- Vue接收后端传过来excel表格的文件流并下载
题外话:当接收文件流时要确定文件流的类型,但也有例外就是application/octet-stream类型,主要是只用来下载的类型,这个类型简单理解意思就是通用类型类似 var .object.ar ...
- activemq实现队列的独有消费
在我们实际的开发中可能存在这么一种情况,应用程序要向一个队列名为queue的队列中发送3条消息,需要保证这3条消息按顺序消费.必须是第一条消费完,在消费第二条然后是第三条.而我们的程序中可能有时候存在 ...
- python re:正则表达式中使用变量
参考:https://www.cnblogs.com/songbiao/p/12422632.html Python中正则表达式的写法,核心就是一个字符串.如下:re.compile(r'表达式')所 ...
- XOR算法
原理 依据的是异或门 即同为0,异为1 0^0=0 0^1=1 1^0=1 1^1=0 对一个数据进行两次XOR运算会得到这个数据本身 所以加密时就将message和其对应的key进行一波XOR运算得 ...
- docker 启动tomcat后,外部访问报HTTP Status 404 – 未找到报错解决
1.检查防火墙,防火墙是关闭的状态 2.检查docker中的tomcat 2.1 使用命令:docker container ps ,查看tomcat运行id 2.2 进入docker的tomcat ...
- Python常用的数据文件存储的4种格式(txt/json/csv/excel)及操作Excel相关的第三方库(xlrd/xlwt/pandas/openpyxl)(2021最新版)
序言:保存数据的方式各种各样,最简单的方式是直接保存为文本文件,如TXT.JSON.CSV等,除此之外Excel也是现在比较流行的存储格式,通过这篇文章你也将掌握通过一些第三方库(xlrd/xlwt/ ...
- 对于multitaper多窗口谱估计的理解及步骤 (对应matlab中pmtm函数)谱减法相关
对于多窗口谱估计的理解 目录 对于多窗口谱估计的理解 0. 缘起 1. PMTM 含义 2. 与我们常用的周期谱估计的区别 3. 计算过程 5. 多窗/单窗谱估计结果对比 6. 程序如何生成多窗 - ...
- VSCode 微信小程序 开发环境配置 详细教程
本博客已暂停更新,需要请转新博客http://www.whbwiki.com/231.html 配置 VsCode 微信小程序开发环境并非不用官方的 微信小程序开发者工具 ,而是两者配合适用,可以极大 ...