【BZOJ 3640】JC的小苹果 (高斯消元,概率DP)
JC的小苹果
Submit: 432 Solved: 159
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 3Sample Output
0.87500000HINT
对于100%的数据 2<=n<=150,hp<=10000,m<=5000,保证图联通。
Source
【分析】
f[i][j]表示剩下i的体力,走到j点的概率。
显然f[hp][1]=1,$Ans=\sum_{i=1}^{hp} f[i][n]$
状态转移:$f[i][j]=f[i+lose[j]][k]*\dfrac{1}{d[k]}$
但是lose[j]有可能为0,状态转移可能成环,这时候就要高斯消元。
lose[j]不为0直接放入常数项。
就写成了$f[i][j]=f[i][k]*\dfrac{1}{d[k]}+...+b[j]$
这样高斯消元是$O(n^{3}*hp)$会超时
发现对于每个i,高斯消元前面部分是一样的,只是常数项变了。于是只做一次高斯消元,然后记录路径,常数项直接照路径做就好了。
【注意如果到达n就不会再走出去了
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define Maxn 160
#define Maxm 5010
#define Maxl 10010
const double eps=1e-; int dcmp(double x)
{
return abs(x)>eps;
} int ls[Maxn];
double f[Maxl][Maxn],d[Maxn];
double a[Maxn][Maxn]; struct node
{
int x,y,next;
}t[Maxm*];
int len,first[Maxn]; void ins(int x,int y)
{
t[++len].x=x;t[len].y=y;
t[len].next=first[x];first[x]=len;
d[x]++;
} int n;
struct hp
{
int x;double y;
}cz[Maxn][Maxn];
int cnt[Maxn];
void gauss()
{
for(int i=;i<=n;i++) cnt[i]=;
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
{
if(dcmp(a[j][i]))
{
double t=a[j][i]/a[i][i];
for(int k=;k<=n;k++) a[j][k]-=a[i][k]*t;
cz[j][++cnt[j]].x=i;cz[j][cnt[j]].y=t;
}
}
} double b[Maxn];
void ffind(int id)
{
for(int i=n;i>=;i--)
{
for(int j=i+;j<=n;j++) b[i]-=f[id][j]*a[i][j];
f[id][i]=b[i]/a[i][i];
}
} int main()
{
int m,hp;
scanf("%d%d%d",&n,&m,&hp);
for(int i=;i<=n;i++) scanf("%d",&ls[i]);
len=;
memset(first,,sizeof(first));
memset(d,,sizeof(d));
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);
if(x!=y) ins(y,x);
}
for(int i=;i<=n;i++) for(int j=;j<=n;j++) a[i][j]=;
for(int i=;i<=n;i++) a[i][i]=1.0; for(int i=;i<=n;i++)
{
if(ls[i]) continue;
for(int j=first[i];j;j=t[j].next)
{
int y=t[j].y;
if(y!=n) a[i][y]-=1.0/d[y];
}
}
gauss();
for(int i=hp;i>=;i--)
{
for(int j=;j<=n;j++) b[j]=;
if(i==hp) b[]=1.0;
for(int j=;j<=n;j++) if(ls[j]&&i+ls[j]<=hp)
{
for(int k=first[j];k;k=t[k].next)
{
int y=t[k].y;
if(y!=n) b[j]+=f[ls[j]+i][y]*1.0/d[y];
}
}
for(int j=;j<=n;j++)
for(int k=cnt[j];k>=;k--)
{
b[j]-=b[cz[j][k].x]*cz[j][k].y;
}
ffind(i);
}
double ans=;
for(int i=;i<=hp;i++) ans+=f[i][n];
printf("%.8lf\n",ans);
return ;
}
2017-04-21 14:40:22
【BZOJ 3640】JC的小苹果 (高斯消元,概率DP)的更多相关文章
- BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡 [高斯消元 概率DP]
1778: [Usaco2010 Hol]Dotp 驱逐猪猡 题意:一个炸弹从1出发p/q的概率爆炸,否则等概率走向相邻的点.求在每个点爆炸的概率 高斯消元求不爆炸到达每个点的概率,然后在一个点爆炸就 ...
- BZOJ 2337: [HNOI2011]XOR和路径 [高斯消元 概率DP]
2337: [HNOI2011]XOR和路径 题意:一个边权无向连通图,每次等概率走向相连的点,求1到n的边权期望异或和 这道题和之前做过的高斯消元解方程组DP的题目不一样的是要求期望异或和,期望之间 ...
- LightOJ 1151 - Snakes and Ladders 高斯消元+概率DP
首先来个期望的论文,讲的非常好,里面也提到了使用线性方程组求解,尤其适用于有向图的期望问题. 算法合集之<浅析竞赛中一类数学期望问题的解决方法> http://www.lightoj.co ...
- Broken robot CodeForces - 24D (三对角矩阵简化高斯消元+概率dp)
题意: 有一个N行M列的矩阵,机器人最初位于第i行和第j列.然后,机器人可以在每一步都转到另一个单元.目的是转到最底部(第N个)行.机器人可以停留在当前单元格处,向左移动,向右移动或移动到当前位置下方 ...
- [luogu2973]driving out the piggies 驱逐猪猡【高斯消元+概率DP】
看到题面的那一刻,我是绝望的ORZ 图论加概率期望加好像不沾边的高斯消元???我人直接傻掉 还没学过概率期望的我果断向题解屈服了(然后还是傻掉了两节课来找线性方程.. Description 奶牛们建 ...
- UVa 10828 Back to Kernighan-Ritchie 高斯消元+概率DP
题目来源:UVa 10828 Back to Kernighan-Ritchie 题意:从1開始 每次等概率从一个点到和他相邻的点 有向 走到不能走停止 求停止时每一个点的期望 思路:写出方程消元 方 ...
- bzoj 2337 高斯消元+概率DP
题目大意: 每条路径上有一个距离值,从1走到N可以得到一个所有经过路径的异或和,求这个异或和的数学期望 这道题直接去求数学期望的DP会导致很难列出多元方程组 我们可以考虑每一个二进制位从1走到N的平均 ...
- light oj 1151 - Snakes and Ladders 高斯消元+概率DP
思路: 在没有梯子与蛇的时候很容易想到如下公式: dp[i]=1+(∑dp[i+j])/6 但是现在有梯子和蛇也是一样的,初始化p[i]=i; 当有梯子或蛇时转移为p[a]=b; 这样方程变为: dp ...
- ●BZOJ 3640 JC的小苹果
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3640题解: 期望dp,高斯消元 设dp[i][h]在i位置且血量为h这个状态的期望经过次数. ...
- [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)
[BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...
随机推荐
- HDU 4521 小明系列问题——小明序列 (线段树 单点更新)
题目连接 Problem Description 大家都知道小明最喜欢研究跟序列有关的问题了,可是也就因为这样,小明几乎已经玩遍各种序列问题了.可怜的小明苦苦地在各大网站上寻找着新的序列问题,可是找来 ...
- Multiple HTTPS Bindings IIS 7 Using appcmd
http://toastergremlin.com/?p=308 Sometimes when using a wildcard SSL or Unified Communications Certi ...
- 浅析XSS与XSSI异同
浅析XSS与XSSI异同 这篇文章主要介绍了XSS与XSSI异同,跨站脚本(XSS)和跨站脚本包含(XSSI)之间的区别是什么?防御方法有什么不同?感兴趣的小伙伴们可以参考一下 Michael Cob ...
- jQuery动态给下拉列表添加一个选项(创建DOM对象)
使用的函数:
- WCF ServiceContract,OperationContract
代码如下 [ServiceContract] //服务协定定义 using System.ServiceModel; public interface IInterface1 { [Operation ...
- cocos2dx中调用TinyXml读取xml配置文件 || cocos2d-x 中跨平台tinyxml读取xml文件方式
TiXmlDocument *doc = newTiXmlDocument; #if (CC_TARGET_PLATFORM ==CC_PLATFORM_ANDROID) //Android平台tin ...
- js实现ctrl+v粘贴图片或是截图
浏览器环境:谷歌浏览器 1.ctrl+v粘贴图片都是监听paste时间实现的,复制的数据都存在clipboardData下面,虽然打印显示数据长度为0,但是还是可以获取数据的 2.打印clipboar ...
- python3实现socket通信
目的:实现两台机器之间的通信.也就是说一个作为服务端(时刻监听接收数据),另一个作为客户端(发送数据). Python实现的过程个人理解: 1.服务端开始监听. 2.客户端发起连接请求. 3.服务端收 ...
- html-示例代码
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/html" xml ...
- cvpr densnet论文