【BZOJ3143】【HNOI2013】游走 && 【BZOJ3270】博物馆 【高斯消元+概率期望】
刚学完 高斯消元,我们来做几道题吧!
T1:【BZOJ3143】【HNOI2013】游走
Description
一个无向连通图,顶点从1编号到N,边从1编号到M。
小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小 Z 到达 N 号顶点时游走结束,总分为所有获得的分数之和。
现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。
Input
第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来MM行每行是整数u,v(1≤u,v≤N)u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边。
输入保证30%的数据满足N≤10,100%的数据满足2≤N≤500且是一个无向简单连通图。
Output
仅包含一个实数,表示最小的期望值,保留3位小数。
题解:
这明显是一道概率期望题嘛!
一条边经过的概率为 $E(u,v)={f_u \over deg_u}+{f_v \over deg_v}$ ,其中u,v为边的两个端点,fx 表示过x点的概率, degx 表示点 x的度数(出度、入度)。
一个点经过的概率为 $f_u=\sum_v f_v\times deg_v$ , v 为与 u 相连的一个节点。
知道了这些,我们还是不能用 dp 求解,因为它不符合决策单调性,即一个点走过去还能走回来,一个点的概率会互相影响,这我们就要列方程求解了。
$$a[i][j]= 1/deg[j]$$
我们这样列一个方程组,不过要注意的是 1号点它是必定经过的所以概率要加 1,n 的概率为 0
然后我们贪心,期望大的编号小。
CODE:
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std; int n,m,u[],v[],deg[];
double a[][],g[],res; void gauss(){
for(int i=,maxn=i;i<n;maxn=++i){
for(int j=i+;j<=n;j++)
if(fabs(a[j][i])>fabs(a[maxn][i]))maxn=j;
for(int j=;j<=n+;j++)swap(a[i][j],a[maxn][j]);
for(int j=i+;j<=n;j++){
if(fabs(a[j][i])<1e-)continue;
double s=a[j][i]/a[i][i];
for(int k=;k<=n+;k++)a[j][k]-=a[i][k]*s;
}
}
for(int i=n;i>=;i--){
for(int j=i+;j<=n;j++)
a[i][n+]-=a[i][j]*a[j][n+];
a[i][n+]/=a[i][i];
}
} int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
scanf("%d%d",u+i,v+i);
deg[u[i]]++,deg[v[i]]++;
}
a[][n+]=-,a[n][n]=;
for(int i=;i<=m;i++){
if(u[i]^n)a[u[i]][v[i]]=1.0/deg[v[i]];
if(v[i]^n)a[v[i]][u[i]]=1.0/deg[u[i]];
}
for(int i=;i<n;i++)a[i][i]=-;
gauss();
for(int i=;i<=m;i++)
g[i]=a[u[i]][n+]/deg[u[i]]+a[v[i]][n+]/deg[v[i]];
sort(g+,g+m+);
for(int i=;i<=m;i++)res+=g[i]*(m-i+);
printf("%.3f\n",res);
}
T2:【BZOJ3270】博物馆
Description
Input
Output
题解:
这回是两个人,同样 id[i][j] 表示 Petya 在 i ,Vasya 在 j 。
设 a[id[x][y]][id[i][j]] 为从状态 id[i][j] 转移到 id[x][y] 的概率来列个方程组
假设现在在 id[i][j] 这个状态上,接下来有这么几种情况
1:两个人同时停留在原点, a[id[i][j]][id[i][j]]=p[i]*p[j] ;
2:第一个人走到了x(前提是i->x有边存在), a[id[x][j]][id[i][j]]+=(1-p[i])/du[i]*p[j] ;
3:第二个人走到了y, a[id[i][y]][id[i][j]]+=p[i]*(1-p[j])/du[j] ;
4:第一个人走到了x,第二个人走到了y, a[id[x][y]][id[i][j]]+=(1-p[i])/du[i]*(1-p[j])/du[j] ;
同上,把方程解出来即可。
CODE:
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std; int n,m,u[],v[],deg[];
double a[][],g[],res; void gauss(){
for(int i=,maxn=i;i<n;maxn=++i){
for(int j=i+;j<=n;j++)
if(fabs(a[j][i])>fabs(a[maxn][i]))maxn=j;
for(int j=;j<=n+;j++)swap(a[i][j],a[maxn][j]);
for(int j=i+;j<=n;j++){
if(fabs(a[j][i])<1e-)continue;
double s=a[j][i]/a[i][i];
for(int k=;k<=n+;k++)a[j][k]-=a[i][k]*s;
}
}
for(int i=n;i>=;i--){
for(int j=i+;j<=n;j++)
a[i][n+]-=a[i][j]*a[j][n+];
a[i][n+]/=a[i][i];
}
} int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
scanf("%d%d",u+i,v+i);
deg[u[i]]++,deg[v[i]]++;
}
a[][n+]=-,a[n][n]=;
for(int i=;i<=m;i++){
if(u[i]^n)a[u[i]][v[i]]=1.0/deg[v[i]];
if(v[i]^n)a[v[i]][u[i]]=1.0/deg[u[i]];
}
for(int i=;i<n;i++)a[i][i]=-;
gauss();
for(int i=;i<=m;i++)
g[i]=a[u[i]][n+]/deg[u[i]]+a[v[i]][n+]/deg[v[i]];
sort(g+,g+m+);
for(int i=;i<=m;i++)res+=g[i]*(m-i+);
printf("%.3f\n",res);
}
【BZOJ3143】【HNOI2013】游走 && 【BZOJ3270】博物馆 【高斯消元+概率期望】的更多相关文章
- 2018.09.23 bzoj3143: [Hnoi2013]游走(dp+高斯消元)
传送门 显然只需要求出所有边被经过的期望次数,然后贪心把边权小的边定城大的编号. 所以如何求出所有边被经过的期望次数? 显然这只跟边连接的两个点有关. 于是我们只需要求出两个点被经过的期望次数. 对于 ...
- bzoj3143: [Hnoi2013]游走(贪心+高斯消元)
考虑让总期望最小,那么就是期望经过次数越多的边贪心地给它越小的编号. 怎么求每条边的期望经过次数呢?边不大好算,我们考虑计算每个点的期望经过次数f[x],那么一条边的期望经过次数就是f[x]/d[x] ...
- 【洛谷3232】[HNOI2013] 游走(贪心+高斯消元)
点此看题面 大致题意: 一个无向连通图,小\(Z\)从\(1\)号顶点出发,每次随机选择某条边走到下一个顶点,并将\(ans\)加上这条边的编号,走到\(N\)号顶点时结束.请你对边进行编号,使总分期 ...
- 【BZOJ-3270】博物馆 高斯消元 + 概率期望
3270: 博物馆 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 292 Solved: 158[Submit][Status][Discuss] ...
- BZOJ 3143 Luogu P3232 [HNOI2013]游走 (DP、高斯消元)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=3143 (luogu) https://www.luogu.org/pro ...
- 【BZOJ-3143】游走 高斯消元 + 概率期望
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2264 Solved: 987[Submit][Status] ...
- BZOJ3270:博物馆(高斯消元)
Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博物馆.这座博物馆有着特别的样式.它包含由m条走廊连接的n间房间,并且满足可以从任何一 ...
- BZOJ3270 博物馆(高斯消元+概率期望)
将两个人各自所在点视为状态,新建一个图.到达某个终点的概率等于其期望次数.那么高斯消元即可. #include<iostream> #include<cstdio> #incl ...
- [JLOI2012]时间流逝 树上高斯消元 概率期望
题面 题意:(感觉题面写的题意是错的?)有\(n\)种能量不同的圈,设当前拥有的圈的集合为\(S\),则: 1,每天有\(p\)概率失去一个能量最小的圈.特别的,如果\(S = \varnothing ...
随机推荐
- UVA 1625 Color Length 颜色的长度 (预处理+dp)
dp[i][j]表示前一个序列拿了i个颜色,后一个序列拿了j个颜色的最小花费. 转移的时候显然只能向dp[i+1][j],或dp[i][j+1]转移,每增加拿走一个颜色,之前已经出现但没结束的颜色个数 ...
- 油猴Tampermonkey 全局函数 它的注入函数都在 onload里面,直接写函数 都是内部函数,外部要是调用,就要挂靠到window上
油猴Tampermonkey 全局函数 它的注入函数都在 onload里面,直接写函数 都是内部函数,外部要是调用,就要挂靠到window上 window.like111 = function (){ ...
- C06 变量和存储类型
目录 全局变量 局部变量 存储类型 全局变量和局部变量 变量的作用域 作用域:某些事物起作用或有效的区域. 变量的使用范围称为变量的作用域. 变量的作用域决定了变量的可操作性和有效性. C语言变量的作 ...
- 人脸识别源代码Open cv
#include <stdio.h> #include <string.h> #include "cv.h" #include "cvaux.h& ...
- 使用xib开发界面
使用xib开发界面 2015-02-02 10:03 编辑: suiling 分类:iOS开发 来源:jymn_chen‘s blog 纯代码写界面有时候会降低开发效率,对于一些通用简单的界面,例 ...
- vue循环出来列表里面的列表点击click事件只对当前列表有效;
<div id="app"> <div class=‘b’ v-for='item in items' @click="toggle(item)&quo ...
- 智能指针之 weak_ptr
1. weak_ptr 介绍 std::weak_ptr 是一种智能指针,它对被 std::shared_ptr 管理的对象存在非拥有性("弱")引用.在访问所引用的对象指针前必须 ...
- SQL 牛刀小试 1 —— 查询操作
#创建数据库create database ST CHARACTER set utf8;#创建用户create user ST identified by '19980510';#授权用户操作该数据库 ...
- 条款52:写了placement new 也要写placement delete(write placement delete if you write placement new)
NOTE: 1.当你写一个placement operator new .请确定也要写出了对应的placement operator delete.如果没有这样做,你的程序可能发生隐晦而时断时续的内存 ...
- 【实验吧】因缺思汀的绕过&&拐弯抹角&&Forms&&天网管理系统
<?php error_reporting(); if (!isset($_POST['uname']) || !isset($_POST['pwd'])) { echo '<form a ...