【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 ...
随机推荐
- python爬虫(1)——urllib包
人生苦短,我用python! 一.关于爬虫 鉴于我的windos环境使用命令行感觉非常不便,也懒得折腾虚拟机,于是我选择了一个折中的办法--Cmder.它的下载地址是:cmder.net Cmder是 ...
- error: Autoconf version 2.67 or higher is required
error: Autoconf version 2.67 or higher is required 今天linux下遇到这种错误,顺便记录下来. #rpm -qf /usr/bin/autoconf ...
- 浏览器中显示PPT的展示效果
发现了一个PPT的WEb展示的方法,在浏览器中载入PDF文件之后,可以实现基于WEB的页面展示,支持全屏与自动播放. https://sharedoc.onk.ninja/ 这不失为一种可行的方式,且 ...
- 谷歌内核浏览器 iframe内容的 tab切换 滚动条消失
问题: 新版本的-webkit- 内核浏览器 在tab切换时,iframe 内容区 丢失滚动条 如下图 (虽然滚动条位置还在,可以垂直滚动,但滚动条不见了) 解决思路: 让iframe重新计算宽高,重 ...
- 使用Netbeans内置的Git工具
在 NetBeans IDE 中使用 Git 支持 NetBeans IDE 为 Git 版本控制客户端提供支持.通过利用 IDE 的 Git 支持,您可以从 IDE 内的项目中直接执行版本控制任务. ...
- Yii高级模板的安装
1,如果你使用composer来安装的话,执行下边两条命令. composer global require "fxp/composer-asset-plugin:^1.2.0" ...
- RegExp正则表达式规则以及常用正则表达式
html,body { font-family: "SF UI Display", ".PingFang SC", "PingFang SC" ...
- POJ - 1190 生日蛋糕 dfs+剪枝
思路:说一下最重要的剪枝,如果当前已经使用了v的体积,为了让剩下的表面积最小,最好的办法就是让R尽量大,因为V = πR 2H,A' = 2πRH,A' = V / R * 2 ,最大的R一定是取当前 ...
- UVA 816 bfs
算法入门经典上面的题.题目链接 uva816 大致题意 有一个最多包含9*9个交叉点的迷宫.输入起点.离开起点时的朝向和终点,求一条最短路(多解时任意输出一个即可).详细题意请看原题 思路 其实就是b ...
- MongoDB,子查询
//1.从sub(订单明细)对订单号分组,查询最多子订单的单号一条数据,重命名orderNo字段为num//2.根据这个sub.num(从结果集里获取第一条结果),查询main(主档表) db.mai ...