洛谷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 傲娇少女幽香是一个很萌很萌的妹子,而且她非常非常地有爱心,很喜欢为幻想乡的人们做一些自己力所能及的事情来帮助他们. 这不,幻想乡突然发生了地震,所有的道路都崩塌了.现在的首要任 ...
随机推荐
- Python笔记 #09# Basic plots with matplotlib
源:DataCamp 气泡的大小表示人口的多少,横坐标表示人均GDP(美元),纵坐标表示预期寿命.-- 作者:Hans Rosling Python 中有许许多多用于可视化的包,而 matplotli ...
- [置顶] SNMPv3认证和加密过程
前面的一些文章详细讲解了SNMPv3的报文内容,下面主要的内容就是SNMPv3的加密和认证过程! USM的定义为实现以下功能: 鉴别 数据加密 密钥管理 时钟同步化 避免延时和重播攻击 1.UsmSe ...
- Docker 版本升级
当前系统版本:Centos 7.4 x64 删除老版本docker sudo yum remove docker docker-common docker-selinux docker-engine ...
- linux及安全《Linux内核设计与实现》第三章——20135227黄晓妍
第三章 (由于linux不区分进程和线程,所以它们在linux中被称为task,也叫任务) 总结:本章主要包括进程以及线程的概念和定义,Linux内核如何管理每个进程,他们在内核中如何被列举,如何创建 ...
- Educational Codeforces Round 47 D
Let's call an undirected graph $G=(V,E)$ relatively prime if and only if for each edge $(v,u)∈E$ $GC ...
- CNN中dropout层的理解
dropout是在训练神经网络模型时,样本数据过少,防止过拟合而采用的trick.那它是怎么做到防止过拟合的呢? 首先,想象我们现在只训练一个特定的网络,当迭代次数增多的时候,可能出现网络对训练集拟合 ...
- Android -- 图片处理, 画画板,缩放,旋转,平移,镜面,倒影,图片合成,颜色处理
1. 画画板 示例代码 public class MainActivity extends Activity { private ImageView iv; private Bitmap baseBi ...
- angular 之路由
1.用angular-cli建一个工程自带路由怎么做? 命令:ng new 项目名 --routing 2.怎么使用路由器和路由器的一些基本使用. //html页面 <a routerLink ...
- 2-14-1 MySQL基础语句,查询语句
一. SQL概述 结构化查询语言(Structured Query Language)简称SQL 1. 它是一种特殊目的的编程语言 2. 它还是一种数据库查询和程序设计语言 (用于存取数据以及查询.更 ...
- Spring Boot 整合Swagger2构建API文档
1.pom.xml中引入依赖 <dependency> <groupId>io.springfox</groupId> <artifactId>spri ...