【BZOJ3640】JC的小苹果

Description

让我们继续JC和DZY的故事。

“你是我的小丫小苹果,怎么爱你都不嫌多!”

“点亮我生命的火,火火火火火!”

话说JC历经艰辛来到了城市B,但是由于他的疏忽DZY偷走了他的小苹果!没有小苹果怎么听歌!他发现邪恶的DZY把他的小苹果藏在了一个迷宫里。JC在经历了之前的战斗后他还剩下hp点血。开始JC在1号点,他的小苹果在N号点。DZY在一些点里放了怪兽。当JC每次遇到位置在i的怪兽时他会损失Ai点血。当JC的血小于等于0时他就会被自动弹出迷宫并且再也无法进入。

但是JC迷路了,他每次只能从当前所在点出发等概率的选择一条道路走。所有道路都是双向的,一共有m条,怪兽无法被杀死。现在JC想知道他找到他的小苹果的概率。

P.S.大家都知道这个系列是提高组模拟赛,所以这是一道送分题balabala

Input

第一行三个整数表示n,m,hp。接下来一行整数,第i个表示jc到第i个点要损失的血量。保证第1个和n个数为0。接下来m行每行两个整数a,b表示ab间有一条无向边。

Output

仅一行,表示JC找到他的小苹果的期望概率,保留八位小数。

Sample Input

3 3 2
0 1 0
1 2
1 3
2 3

Sample Output

0.87500000

HINT

对于100%的数据 2<=n<=150,hp<=10000,m<=5000,保证图联通。

题解:如果没有Ai=0,直接DP,如果hp很小,直接高斯消元,但是都有,所以用DP+高斯消元。

发现,方程组中只有Ai=0的点有系数,Ai!=0的都可以直接拿过来变成常数项,所以每次我们的方程组只有一列是变化的,所以我们将方程组表示成Ax=b,x=A-1b。x和b都是列向量。所以我们只需要预处理出A的逆,然后每次O(n2)乘一下就行了。

矩阵求逆的方法:先将(A|I)拼一起,然后通过行变换将左边的A消成I,右边剩下的就是A-1

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
int n,m,hp;
int dam[160],pa[5010],pb[5010],d[160];
double f[160][10000],B[160],ans;
struct M
{
double v[160][160];
M (){memset(v,0,sizeof(v));}
double* operator [](int x) {return v[x];}
void I()
{
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) v[i][j]=(i==j)?1:0;
}
M getinv()
{
int i,j,k;
M re;
double t;
re.I();
for(i=1;i<=n;i++)
{
for(j=i;j<=n;j++) if(fabs(v[j][i])>fabs(v[i][i])) for(k=1;k<=n;k++)
swap(v[i][k],v[j][k]),swap(re[i][k],re[j][k]);
t=v[i][i];
for(j=1;j<=n;j++) v[i][j]/=t,re[i][j]/=t;
for(j=1;j<=n;j++) if(i!=j)
{
t=v[j][i];
for(k=1;k<=n;k++) v[j][k]-=t*v[i][k],re[j][k]-=t*re[i][k];
}
}
return re;
}
void operator * (int x)
{
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][x]+=v[i][j]*B[j];
}
};
M A,A1;
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd(),hp=rd();
int i,j;
for(i=1;i<=n;i++) dam[i]=rd();
for(i=1;i<=m;i++)
{
pa[i]=rd(),pb[i]=rd();
d[pa[i]]++;
if(pa[i]!=pb[i]) d[pb[i]]++;
}
for(i=1;i<=m;i++)
{
if(!dam[pb[i]]) A[pb[i]][pa[i]]-=1.0/d[pa[i]];
if(pa[i]==pb[i]) continue;
if(!dam[pa[i]]) A[pa[i]][pb[i]]-=1.0/d[pb[i]];
}
for(i=1;i<=n;i++) A[i][n]=0;
for(i=1;i<=n;i++) A[i][i]++;
A1=A.getinv();
for(j=hp;j;j--)
{
for(i=1;i<=n;i++) B[i]=0;
if(j==hp) B[1]=1;
else for(i=1;i<=m;i++)
{
if(dam[pb[i]]&&dam[pb[i]]+j<=hp&&pa[i]!=n) B[pb[i]]+=f[pa[i]][j+dam[pb[i]]]*1.0/d[pa[i]];
if(pa[i]==pb[i]) continue;
if(dam[pa[i]]&&dam[pa[i]]+j<=hp&&pb[i]!=n) B[pa[i]]+=f[pb[i]][j+dam[pa[i]]]*1.0/d[pb[i]];
}
A1*j,ans+=f[n][j];
}
printf("%.8lf",ans);
return 0;
}

【BZOJ3640】JC的小苹果 概率DP+高斯消元的更多相关文章

  1. BZOJ 3640: JC的小苹果 [概率DP 高斯消元 矩阵求逆]

    3640: JC的小苹果 题意:求1到n点权和\(\le k\)的概率 sengxian orz的题解好详细啊 容易想到\(f[i][j]\)表示走到i点权为j的概率 按点权分层,可以DP 但是对于\ ...

  2. BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元

    BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元 题意: 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 3 ...

  3. LightOJ - 1151概率dp+高斯消元

    概率dp+高斯消元 https://vjudge.net/problem/LightOJ-1151 题意:刚开始在1,要走到100,每次走的距离1-6,超过100重来,有一些点可能有传送点,可以传送到 ...

  4. 【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元

    题目描述 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两 ...

  5. BZOJ3270 博物館 概率DP 高斯消元

    BZOJ3270 博物館 概率DP 高斯消元 @(XSY)[概率DP, 高斯消元] Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博 ...

  6. BZOJ 3270: 博物馆 [概率DP 高斯消元]

    http://www.lydsy.com/JudgeOnline/problem.php?id=3270 题意:一张无向图,一开始两人分别在$x$和$y$,每一分钟在点$i$不走的概率为$p[i]$, ...

  7. 【概率DP/高斯消元】BZOJ 2337:[HNOI2011]XOR和路径

    2337: [HNOI2011]XOR和路径 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 682  Solved: 384[Submit][Stat ...

  8. LightOJ 1151 Snakes and Ladders(概率DP + 高斯消元)

    题意:1~100的格子,有n个传送阵,一个把进入i的人瞬间传送到tp[i](可能传送到前面,也可能是后面),已知传送阵终点不会有另一个传送阵,1和100都不会有传送阵.每次走都需要掷一次骰子(1~6且 ...

  9. 2016ACM/ICPC亚洲区沈阳站H - Guessing the Dice Roll HDU - 5955 ac自动机+概率dp+高斯消元

    http://acm.hdu.edu.cn/showproblem.php?pid=5955 题意:给你长度为l的n组数,每个数1-6,每次扔色子,问你每个串第一次被匹配的概率是多少 题解:先建成ac ...

随机推荐

  1. 关于可变参数列表stdarg

    1.对于可变参数 可变参数列表通过stdarg.h中的宏实现: 主要有一个va_list类型 三个宏:va_start,va_arg,va_end; va_start格式: va_start(argu ...

  2. zabbix自动化监控之自动注册

    自动注册与自动发现刚好相反,是zabbix agent主动联系zabbix server,最后由zabbix server将这些agent加到host里.活动的Zabbix agent可以自动注册到服 ...

  3. WINDOWS 2003系统时间24小时制与12小时显示格式不一致问题与解决

    WINDOWS 2003 SERVER系统时间24小时制与12小时格式不一致问题,而导致论坛或BLOG不能正常显示更新日期的问题及解决方法问题的方法. 在WIN2003上出现这种情况的原因是在程序中使 ...

  4. 转: 由socket的accept说开去

    from: http://ticktick.blog.51cto.com/823160/779866 今天与同学争执一个话题:由于socket的accept函数在有客户端连接的时候产生了新的socke ...

  5. include file与jsp:include 的区别

    <%include   file="a.jsp"%>静态包含,先加入再编译,就是在编译的时候将a.jsp的代码加入进来在编译,只会生成一个servlet文件,而且不同a ...

  6. 获取web应用路径 // "/" 表示class 根目录

    /** * 获取web应用路径 * @Description : 方法描述 * @Method_Name : getRootPath * @return * @return : String * @C ...

  7. 一个RecycleView的强大adapter

    代码地址如下:http://www.demodashi.com/demo/12218.html 前言 一般我们要在mainActivity中利用RecycleView展示一个列表数据的时候,adapt ...

  8. Prometheus入门

    什么是TSDB? TSDB(Time Series Database)时序列数据库,我们可以简单的理解为一个优化后用来处理时间序列数据的软件,并且数据中的数组是由时间进行索引的. 时间序列数据库的特点 ...

  9. 代码设置UIButton文字、图片位置

    假设有按钮rButton的 imageEdgeInsets和contentEdgeInsets可以设置按钮的标题和图片的位置,如下代码,设置标题居右 NSString * rBtnTitle = @& ...

  10. 0x00 使用Ant 设置项目

    1. Ant 简介: Ant 是一款广泛使用的流行的开源构建工具,它用Java语言编写. 2.Ant官网: Ant官网:http://ant.apache.org/ 3.设置环境变量: 新建 Vari ...