洛谷3343(ZJOI2015)地震后的幻想乡
题目:https://www.luogu.org/problemnew/show/P3343
1.那个时间与边的大小排名有关,所以需要求一下最大边的期望排名就行。
2.期望排名是这样算的:(排名为1的概率 * 1(1的值) + 排名为2的概率 * 2 + ……) / (m+1)
仔细一想可以变成这样:(排名>=1的概率 + 排名>=2的概率 + ……) / (m+1)
可以是这样?——(连0时不能联通的概率 + 连1时不能联通的概率 + ……) / (m+1)
这里的0、1等可以看作是“前几条边”,也就是“几条边”;
3.这些概率不用每一步都就是概率,可以算的是方案、最后再除以所有方案数;
这个“几条边”的方案可以用dp来推(只要注意转移到它的状态里的边不重复)!状压记录点集。
发现 用了 i 条边不连通的方案数 + 用了 i 条边连通的方案数 = 从m条边里选 i 条边的方案数,所以求出一个就能算出另一个了。
如果求“用了 i 条边连通的方案数”,每一种情况由三部分构成:一条边和这条边两边的两个点集;
我们需要枚举一条被选的边,再枚举一个端点的点集,剩下的点构成另一个点集,这两个点集的“连通”方案数相乘(还要枚举其中一个点集用了多少条边)。
但状态里记录的是点集,要枚举那条边有点麻烦。
如果求“用了 i 条边不连通的方案数”,每一种情况就只由两个点集转移来,无需有中间那条边;
枚举这两个点集时为了不重不漏,可以确定一个“划分点”,枚举的那个点集必须包含它,并限制枚举的这个点集是连通的;然后剩下的点随便连边(组合数)。
(2018.6.16 PS:这个点必须被限制在一个连通块里。不能把它限制在随便的那个部分里,会重复。一条边也没有的图就是一个例子。)
4.代码里:组合数的赋初值!别忘了zh[0][0]!!还应注意一些地方从0或从1开始。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,dp[][][(<<)+],lm;
int siz[(<<)+],zh[][];
int head[],num[<<],pre[];
double ans;
bool vis[],in[],ed[];
struct Edge{
int next,to;
Edge(int n=,int t=):next(n),to(t) {}
}edge[];
int dfs(int cur)
{
vis[cur]=;int ret=;
for(int i=head[cur],v;i;i=edge[i].next)
if(in[v=edge[i].to])
{
if(!ed[i])ret++,ed[i]=;
if(!vis[v])ret+=dfs(v);
}
return ret;
}
void init()
{
lm=(<<n);
for(int i=;i<=n;i++)num[<<(i-)]=i;
for(int i=;i<lm;i++)
{
int k=i;
memset(ed,,sizeof ed);memset(vis,,sizeof vis);
memset(in,,sizeof in);
while(k)in[num[k&(-k)]]=,k-=(k&(-k));
for(int j=;j<=n;j++)if(in[j])siz[i]+=dfs(j);siz[i]>>=;
}
zh[][]=;//!!!!!!!
for(int i=;i<=m;i++)
{
zh[][i]=;
for(int j=;j<i;j++)
zh[j][i]=zh[j][i-]+zh[j-][i-];
zh[i][i]=;
}
for(int i=;i<lm;i++)dp[][][i]=;
for(int i=;i<=n;i++)dp[][][<<(i-)]=,dp[][][<<(i-)]=;
}
int main()
{
// freopen("zjsc.out","w",stdout);
scanf("%d%d",&n,&m);int u,v;
for(int i=;i<=m;i++)
{
scanf("%d%d",&u,&v);
edge[i]=Edge(head[u],v);head[u]=i;
edge[i+m]=Edge(head[v],u);head[v]=i+m;
// dp[1][1][(1<<(u-1))|(1<<(v-1))]=1;
}
init();
// for(int i=1;i<lm;i++)if(!dp[1][1][i])dp[0][1][i]=1;
for(int i=;i<=m;i++)
for(int s=;s<lm;s++)
{
int k=;for(;(s&(<<(k-)))==;k++);
for(int c=((s-)&s);c;c=((c-)&s))
if(c&(<<(k-)))
{
// if(i==1)printf("s=%d c=%d\n",s,c);
for(int j=;j<=i;j++)//0~i
{
// if(i==1&&j==1)printf(" dp1=%d\n",dp[1][j][c]);
dp[][i][s]+=dp[][j][c]*zh[i-j][siz[s^c]];
// if(i==1&&s==7&&c==5)
// printf("j=%d dp1jc=%d zh=%d dp0is=%d\n",
// j,dp[1][j][c],zh[i-j][siz[s^c]],dp[0][i][s]);
// if(i==1&&dp[0][i][s])printf("j=%d s=%d dp0=%d\n",j,s,dp[0][i][s]);
}
}
dp[][i][s]=zh[i][siz[s]]-dp[][i][s];
// if(i==1)printf("(s=%d dp1=%d)\n",s,dp[1][i][s]);
}
// for(int i=1;i<=n;i++)
// {
// pre[i]=dp[0][i-1][lm-1]-dp[0][i][lm-1];
// pre[i]/=zh[i][n];
// }
// for(int i=1;i<=n;i++)
// ans+=(double)i/(n+1)*pre[i];
for(int i=;i<m;i++)ans+=(double)dp[][i][lm-]/(double)zh[i][m];//其实是<m,但dp[0][m][lm-1]肯定是0
printf("%.6lf",(double)ans/(double)(m+));//已求者为排名期望
return ;
}
洛谷3343(ZJOI2015)地震后的幻想乡的更多相关文章
- [bzoj3925] [洛谷P3343] [ZJOI2015] 地震后的幻想乡
Description 傲娇少女幽香是一个很萌很萌的妹子,而且她非常非常地有爱心,很喜欢为幻想乡的人们做一些自己力所能及的事情来帮助他们. 这不,幻想乡突然发生了地震,所有的道路都崩塌了.现在的首要任 ...
- 洛谷P3343 [ZJOI2015]地震后的幻想乡 [DP,概率期望]
传送门 思路 题目给了一个提示:对于\(n\)个\([0,1]\)的随机变量,其中第\(k\)小的期望大小是\(\frac{k}{n+1}\). 这引导我们枚举边的相对大小的全排列,然后求最小生成树 ...
- 洛谷 P3343 - [ZJOI2015]地震后的幻想乡(朴素状压 DP/状压 DP+微积分)
题面传送门 鸽子 tzc 竟然来补题解了,奇迹奇迹( 神仙题 %%%%%%%%%%%% 解法 1: 首先一件很明显的事情是这个最小值可以通过类似 Kruskal 求最小生成树的方法求得.我们将所有边按 ...
- 【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)
题目描述 傲娇少女幽香是一个很萌很萌的妹子,而且她非常非常地有爱心,很喜欢为幻想乡的人们做一些自己力所能及的事情来帮助他们. 这不,幻想乡突然发生了地震,所有的道路都崩塌了.现在的首要任务是尽快让幻想 ...
- BZOJ3925: [Zjoi2015]地震后的幻想乡【概率期望+状压DP】
Description 傲娇少女幽香是一个很萌很萌的妹子,而且她非常非常地有爱心,很喜欢为幻想乡的人们做一些自己力所能及的事情来帮助他们. 这不,幻想乡突然发生了地震,所有的道路都崩塌了.现在的首要任 ...
随机推荐
- Linux内核分析第一周-通过分析汇编代码理解计算机是如何工作的
首先,我们先写一个简单的C语言程序,如下: int g(int x) { return x +3; } int f(int x) { return g(x); } int main(void) { r ...
- FZU 2280 Magic(字符串Hash)题解
题意:给你n个字符串,每个字符串有一个值w,有q次询问,一共两种操作:一是“1 x y”表示把第x个串的w变为y:二是“2 x”,输出第x个串能放几次魔法.放魔法的条件是这样:用串x放魔法,如果在1~ ...
- Linux中重定向--转载
转:http://blog.csdn.net/songyang516/article/details/6758256 1重定向 1.1 重定向符号 > 输出 ...
- 在多节点上运行分布式Intel Caffe
一般有2种并行模式:数据并行(Data parallelism)和模型并行(model parallelism). 在模型并行化( model parallelism )方法里,分布式系统中的不同机器 ...
- 将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class、缺少 xsd、重复打包依赖)
最近在看 spring boot 的东西,觉得很方便,很好用.对于一个简单的REST服务,都不要自己部署Tomcat了,直接在 IDE 里 run 一个包含 main 函数的主类就可以了. 但是,转念 ...
- MyBatise代码自动生成时候Oralce的number类型BigDecimal问题
使用MyBatise的代码自动生成工具时候,即便在配置文件中定义了 <javaTypeResolver> <property name="forceBigDecimals& ...
- 关于 XML 头声明和standalone 的解释
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <roo ...
- 面筋: 奇虎360 c++ 后台开发 实习生 面试
投的是360上海的商业化部门,岗位是C++服务端开发实习生,记录一下面试历程: 视频面试,但是是有代码框让你写代码的. 一面: Q:先说一下个人信息,做过的项目 A:.......... Q:先写个翻 ...
- HP-UX 下用户被锁
/usr/lbin/getprpw -m lockout root 如果返回lockout=0000000 该帐号是非锁定的,如果是其它的如:lockout=0001000则表示该帐号被锁定 如果是测 ...
- ansible入门02
1.常用模块 1.1 group模块 添加或删除组 name= state=:present(添加),absent(删除) sy ...