洛谷 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)
题目描述 傲娇少女幽香是一个很萌很萌的妹子,而且她非常非常地有爱心,很喜欢为幻想乡的人们做一些自己力所能及的事情来帮助他们. 这不,幻想乡突然发生了地震,所有的道路都崩塌了.现在的首要任务是尽快让幻想 ...
随机推荐
- javascript-原生-闭包
1.变量的作用域 前提:这里只全部都通过var创建的变量或对象 1.全局变量:函数外创建变量 var x=10; function test(){ alert("全局变量在test函数中&q ...
- py3.8安装
ubantu python3.8# 命令下载wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tar.xz#解压tar -xvJf P ...
- [no_code]OCR表格处理——功能规格说明书
项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 功能规格说明书 我们在这个课程的目标是 远程协同工作,采用最新技术开发软件 这个作业在哪个具体方面 ...
- qgis cookbook-QgsMapRendererJob学习
学习到渲染(QgsMapRendererJob),按照教程所讲总是输出不了图像,看了一下qgis的测试源码,发现少了一句话,加上后就可以输出了! from qgis.core import * fro ...
- Linux入门需要搞清楚的思路问题
很多同学接触linux不多,对linux平台的开发更是一无所知. 而现在的趋势越来越表明,作为一个优秀的软件开发人员,或计算机it行业从业人员,="" 掌握linux是一种很重要的 ...
- 种类并查集(维护敌人的敌人是朋友)、并行-poj1182-食物链 笔记
题意 输入若干组数据,代表着不同动物在食物链的位置(A,B,C),要求出在输入的过程中有多少组数据会与之前矛盾. 思路(借鉴挑战程序设计竞赛) 这题是学并查集时的题,所以用了并查集. 一开始我想的是, ...
- Linux Shell Here Document
Here Document 是一种有特殊用处的代码块,他使用IO重定向的形式记录了一段临时的文本或交互命令,并且把这些文本或命令 依次的传递给一个程序或一个命令,作为他运行时的标准输入. Here d ...
- 恶意代码分析实战五:OllyDebug动态结合
目录 恶意代码分析实战五:OllyDebug动态结合 OllyDebug界面介绍 OllyDebug载入程序方法 OllyDebug地址跳转 OllyDebug下断点 OllyDebug单步执行 Ol ...
- Gitee图床设置
https://gitee.com/ 创建新仓库 点击右上角加号->新建仓库,填写基本信息后点击下面的创建即可 https://gitee.com/projects/new 创建新令牌 点击设置 ...
- 『学了就忘』Linux基础命令 — 26、帮助命令
目录 1.man命令 (1)man命令的快捷键 (2)man命令的帮助级别(了解即可) (3)man命令的使用 2.info命令 3.help命令 4.--help选项 1.man命令 man是最常见 ...