题解

我们考虑列出期望方程组,\(dp[i][j]\)表示在第\(i\)个点血量为\(j\)的时候到达\(N\)点的概率,所有的\(dp[N][j]\)都是1,所有\(j < 0\)都是0

答案是\(dp[1][hp]\)

\(dp[u][j] = \sum_{v} \frac{1}{deg[u]}dp[v][j - a[v]]\)

我们发现这个方程在j不同的时候,只有常数项发生改变,剩下的系数不变

于是我们把常数项变成一个列向量,把需要消元的系数矩阵求一个逆,每次计算常数项,用常数项乘逆矩阵得到每一个血量的\(dp\)值即可

注意判自环= =

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N,M,hp,deg[155],blood[155];
struct node {
int to,next;
}E[100005];
int sumE,head[155];
db b[155],dp[155][10005],c[155];
void add(int u,int v) {
E[++sumE].next = head[u];
E[sumE].to = v;
head[u] = sumE;
}
struct Matrix {
db f[155][155];
Matrix() {memset(f,0,sizeof(f));}
void unit() {
for(int i = 1 ; i <= N ; ++i) {
f[i][i] = 1.0;
}
}
friend Matrix operator * (const Matrix &a,const Matrix &b) {
Matrix c;
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= N ; ++j) {
for(int k = 1 ; k <= N ; ++k) {
c.f[i][j] += a.f[i][k] * b.f[k][j];
}
}
}
return c;
}
friend Matrix operator ~(Matrix a) {
Matrix b;
b.unit();
for(int i = 1 ; i <= N ; ++i) {
int l = i;
for(int j = i + 1; j <= N ; ++j) {
if(fabs(a.f[j][i]) > fabs(a.f[l][i])) l = j;
}
if(i != l) {
for(int j = 1 ; j <= N ; ++j) {
swap(a.f[i][j],a.f[l][j]);
swap(b.f[i][j],b.f[l][j]);
}
}
db t = 1.0 / a.f[i][i];
for(int j = 1 ; j <= N ; ++j) {
a.f[i][j] *= t;
b.f[i][j] *= t;
} for(int j = 1 ; j <= N ; ++j) {
if(i == j) continue;
db t = a.f[j][i];
for(int k = 1 ; k <= N ; ++k) {
a.f[j][k] -= t * a.f[i][k];
b.f[j][k] -= t * b.f[i][k];
}
}
}
return b;
}
}A;
void Solve() {
read(N);read(M);read(hp);
int u,v;
for(int i = 1 ; i <= N ; ++i) read(blood[i]);
for(int i = 1 ; i <= M ; ++i) {
read(u);read(v);
if(u == v) {add(u,v);++deg[u];}
else {add(u,v);add(v,u);++deg[u];++deg[v];}
}
for(int u = 1 ; u <= N ; ++u) {
if(u == N) {
b[u] = 1;A.f[u][u] = 1;continue;
}
A.f[u][u] = 1;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v == N) {b[u] += 1.0 / deg[u];}
else if(blood[v] == 0){
A.f[v][u] -= 1.0 / deg[u];
}
}
}
A = ~A;
for(int i = 1 ; i <= hp ; ++i) {
for(int u = 1 ; u <= N ; ++u) {
c[u] = b[u];
if(u == N) continue;
for(int h = head[u] ; h ; h = E[h].next) {
int v = E[h].to;
if(blood[v] && i > blood[v]) {
c[u] += (1.0 / deg[u]) * dp[v][i - blood[v]];
}
}
}
for(int u = 1 ; u <= N ; ++u) {
for(int k = 1 ; k <= N ; ++k) {
dp[u][i] += c[k] * A.f[k][u];
}
}
}
printf("%.8lf\n",dp[1][hp]);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

【BZOJ】3640: JC的小苹果的更多相关文章

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

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

  2. BZOJ 3640: JC的小苹果

    3640: JC的小苹果 Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 425  Solved: 155[Submit][Status][Discus ...

  3. BZOJ 3640 JC的小苹果(逆矩阵)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3640 题意:给出一个无向图,从1走到n.开始是血量H,从u到达v时血量减少a[v] ...

  4. ●BZOJ 3640 JC的小苹果

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3640题解: 期望dp,高斯消元 设dp[i][h]在i位置且血量为h这个状态的期望经过次数. ...

  5. 3640: JC的小苹果 - BZOJ

    让我们继续JC和DZY的故事.“你是我的小丫小苹果,怎么爱你都不嫌多!”“点亮我生命的火,火火火火火!”话说JC历经艰辛来到了城市B,但是由于他的疏忽DZY偷走了他的小苹果!没有小苹果怎么听歌!他发现 ...

  6. 【BZOJ 3640】JC的小苹果 (高斯消元,概率DP)

    JC的小苹果 Submit: 432  Solved: 159 Description 让我们继续JC和DZY的故事. “你是我的小丫小苹果,怎么爱你都不嫌多!” “点亮我生命的火,火火火火火!” 话 ...

  7. 【BZOJ3640】JC的小苹果 概率DP+高斯消元

    [BZOJ3640]JC的小苹果 Description 让我们继续JC和DZY的故事. “你是我的小丫小苹果,怎么爱你都不嫌多!” “点亮我生命的火,火火火火火!” 话说JC历经艰辛来到了城市B,但 ...

  8. bzoj千题计划291:bzoj3640: JC的小苹果

    http://www.lydsy.com/JudgeOnline/problem.php?id=3640 dp[i][j] 表示i滴血到达j的概率 dp[i][j] = Σ dp[i+val[i]][ ...

  9. BZOJ3640 : JC的小苹果

    设$f[i][j]$表示$hp$为$i$,在$j$点的概率,$d[i]$表示$i$的度数,$w[i]$表示经过$i$点要扣掉的血量. 对于$j$到$k$这条边,$f[i-w[k]][k]+=\frac ...

随机推荐

  1. Django_在单独文件中加载Django环境临时调试

    创建Django环境后,每次在打印调试都需要基于项目有些麻烦. 如何在项目外的文件中加载项目环境进行便携的调试? 创建一个新的 orm.py import os if __name__ == '__m ...

  2. 【转】keil5 missing close quote 错误解决

    在使用utf8保存文件的情况下,代码中出现中文字符串会提示missing close quote解决:Options for Target --> C/C++ --> Misc Contr ...

  3. 获取C++类成员虚函数地址

    1.GCC平台 GCC平台获取C++成员虚函数地址可使用如下方法[1]: class Base{ int i; public: virtual void f1(){ cout<<" ...

  4. 【BZOJ 3451】Tyvj1953 Normal 思维题+期望概率+FFT+点分治

    我感觉是很强的一道题……即使我在刷专题,即使我知道这题是fft+点分治,我仍然做不出来……可能是知道是fft+点分治限制了我的思路???(别做梦了,再怎样也想不出来的……)我做这道题的话,一看就想单独 ...

  5. 洛谷P2469 星际竞速

    上下界费用流比较无脑,提供一种更巧妙的费用流,无需上下界. #include <cstdio> #include <algorithm> #include <queue& ...

  6. java基础基础总结----- RunTime

  7. python的内置模块re模块方法详解以及使用

    正则表达式 一.普通字符 .     通配符一个.只匹配一个字符 匹配任意除换行符"\n"外的字符(在DOTALL模式中也能匹配换行符 >>> import re ...

  8. vue-cli内部webpack的打包优化

    在此之前,我们先谈谈前端项目的性能优化. 优化前端项目无非就是2方面的优化: 一.网络性能优化(重点) 减少请求数量(webpack的天职就是打包) 减少请求资源大小(压缩gzip,后端会完成) CD ...

  9. VMware ESXI6.0服务器安装

    1.制作一个ESXI6.0的系统安装盘 2.服务器启动后加载VMware ESXi 6.0的ISO文件,开始安装. 3.ESXi引导装入程序,VMware ESXi引导过程,在屏幕上方显示的版本号.内 ...

  10. Mybatis 使用 mapper 接口规范的 一对一, 一对多,多对多映射

    首先的 是 最原始的 pojo 类来 做简单映射 简单 pojo 映射: <mapper namespace="com.ghc.dao.UserDao"> <se ...