【BZOJ3143】游走(高斯消元,数学期望)
【BZOJ3143】游走(高斯消元,数学期望)
题面
题解
首先,概率不会直接算。。。
所以来一个逼近法算概率
这样就可以求出每一条边的概率
随着走的步数的增多,答案越接近
(我卡到\(5000\)步可以拿\(50\)分)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 520
#define MAXL 500000
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next;}e[MAXL];
int h[MAX],cnt=2;
int n,m,op[MAX];
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;op[u]++;}
double V[MAX*MAX];
double f[2][MAX];
int main()
{
n=read();m=read();
for(int i=1;i<=m;++i)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
}
f[0][1]=1;
for(int st=1,nw=1,nt=0;st<=5000;++st,nw^=1,nt^=1)
{
for(int i=1;i<=n;++i)f[nw][i]=0;
for(int u=1;u<n;++u)
for(int i=h[u];i;i=e[i].next)
V[i>>1]+=f[nt][u]/op[u],f[nw][e[i].v]+=f[nt][u]/op[u];
}
sort(&V[1],&V[m+1]);
double ans=0;
for(int i=m;i;--i)
ans+=i*V[m-i+1];
printf("%.3lf\n",ans);
return 0;
}
这样子算出来会有精度问题
所以就挂了
现在考虑怎么算这个概率
显然不能\(dp\)
那么,看看每一个点的概率是怎么来的
\]
其中,\(op[u]\)是\(u\)的出度
那么,现在我有\(n\)个未知数(每个的概率)
以及\(n\)个方程(每个点的概率就是怎么算出来的)
大力用高斯消元解一下就好了
算出来之后贪心
就没有问题啦
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 520
#define MAXL 500000
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next;}e[MAXL];
int h[MAX],cnt=2;
int n,m,op[MAX];
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;op[u]++;}
double V[MAX*MAX];
double g[MAX][MAX];
double f[MAX];
void Build()
{
for(int i=1;i<=n;++i)g[i][i]=1;
for(int u=1;u<n;++u)
for(int i=h[u];i;i=e[i].next)
g[e[i].v][u]-=1.0/op[u];
g[1][n+1]=1;
}
void Guess()
{
for(int i=1;i<=n;++i)
{
double bs=g[i][i];
for(int j=1;j<=n+1;++j)g[i][j]/=bs;
for(int j=i+1;j<=n;++j)
{
bs=g[j][i];
for(int k=1;k<=n+1;++k)
g[j][k]-=g[i][k]*bs;
}
}
for(int i=n;i;--i)
{
f[i]=g[i][n+1];
for(int j=i-1;j;--j)
g[j][n+1]-=f[i]*g[j][i];
}
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;++i)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
}
Build();Guess();
for(int u=1;u<n;++u)
for(int i=h[u];i;i=e[i].next)
V[i>>1]+=f[u]/op[u];
double ans=0;
sort(&V[1],&V[m+1]);
for(int i=m;i;--i)
ans+=i*V[m-i+1];
printf("%.3lf\n",ans);
return 0;
}
【BZOJ3143】游走(高斯消元,数学期望)的更多相关文章
- 【BZOJ-3143】游走 高斯消元 + 概率期望
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2264 Solved: 987[Submit][Status] ...
- [HNOI2013][BZOJ3143] 游走 - 高斯消元
题目描述 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边 ...
- Luogu3232 HNOI2013 游走 高斯消元、期望、贪心
传送门 这种无向图上从一个点乱走到另一个点的期望题目好几道与高斯消元有关 首先一个显然的贪心:期望经过次数越多,分配到的权值就要越小. 设$du_i$表示$i$的度,$f_i$表示点$i$的期望经过次 ...
- BZOJ 3143 HNOI2013 游走 高斯消元 期望
这道题是我第一次使用高斯消元解决期望类的问题,首发A了,感觉爽爽的.... 不过笔者在做完后发现了一些问题,在原文的后面进行了说明. 中文题目,就不翻大意了,直接给原题: 一个无向连通图,顶点从1编号 ...
- 【BZOJ3143】【HNOI2013】游走 高斯消元
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3143 我们令$P_i$表示从第i号点出发的期望次数.则$P_n$显然为$0$. 对于$P ...
- bzoj 3143: [Hnoi2013]游走 高斯消元
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1026 Solved: 448[Submit][Status] ...
- 【xsy1201】 随机游走 高斯消元
题目大意:你有一个$n*m$的网格(有边界),你从$(1,1)$开始随机游走,求走到$(n,m)$的期望步数. 数据范围:$n≤10$,$m≤1000$. 我们令 $f[i][j]$表示从$(1,1) ...
- BZOJ3143:[HNOI2013]游走(高斯消元)
Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点, ...
- 高斯消元与期望DP
高斯消元可以解决一系列DP序混乱的无向图上(期望)DP DP序 DP序是一道DP的所有状态的一个排列,使状态x所需的所有前置状态都位于状态x前: (通俗的说,在一个状态转移方程中‘=’左侧的状态应该在 ...
- HDU4870_Rating_双号从零单排_高斯消元求期望
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870 原题: Rating Time Limit: 10000/5000 MS (Java/Other ...
随机推荐
- HashMap----工作原理
先来些简单的问题 "你用过HashMap吗?" "什么是HashMap?你为什么用到它?" 几乎每个人都会回答"是的",然后回答HashMa ...
- ubuntu中gdb调试工具的使用
首先有一段.c代码 1.可调试gcc编译:gcc -g -o xxx xxx.c 2.启动gdb调试 gdb xxx 3.在main函数处设置断点 break main 4.运行程序 run 5.其他 ...
- 940D Alena And The Heater
传送门 题目大意 给出两个长度为N的数组A,B,以及一种计算规律: 若t[i]=1,需满足t[i-1]=t[i-2]=t[i-3]=t[i-4]=0,以及max{A[i],A[i-1],A[i-2], ...
- [SCOI2009][bzoj1025]游戏
[SCOI2009][bzoj1025]游戏 标签: DP 置换 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1025 题解 很套路的题目 ...
- 【学习笔记】Hibernate 一对一关联映射 组件映射 二级缓存 集合缓存
啊讲道理放假这十天不到啊 感觉生活中充满了绝望 这就又开学了 好吧好吧继续学习笔记?还是什么的 一对一关联映射 这次我们仍然准备了两个表 一个是用户表Users 一个是档案表Resume 他们的关系是 ...
- Linux系统上安装JDK1.8
1,下载jdk1.8 首先进入jdk下载目录:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213315 ...
- 《android开发艺术探索》读书笔记(五)--RemoteViews
接上篇<android开发艺术探索>读书笔记(四)--View工作原理 No1: RemoteViews使用场景:通知栏和桌面小部件 No2: 通知栏主要通过NotificationMan ...
- hihoCoder 1523 数组重排2 贪心
题意:给定一个1-N的排列A1, A2, - AN,每次操作小Hi可以选择一个数,把它放到数组的最左边. 请计算小Hi最少进行几次操作就能使得新数组是递增排列的. 思路:最后的序列是递增的,那么必定满 ...
- Spring IO Platform 解决Spring项目组合中版本依赖
简介: Spring IO Platform是Spring官网中排第一位的项目.它将Spring的核心API集成到一个适用于现代应用程序的平台中.提供了Spring项目组合中的版本依赖.这些依赖关系是 ...
- layui的几个简单使用(简单弹窗,加载效果,移除加载效果)
1.加载效果和移除加载效果 function layuiLoading(msg){ layui.use(['layer', 'form'], function(){ index = layer.loa ...