对于每个点两个方向(两头只有一个方向)建一个点,然后预处理出每个点走k(1≤k≤n)k(1\le k\le n)k(1≤k≤n)到哪个点,列出方程式高斯消元就行了。记得前面bfsbfsbfs出那些点不可到,他们的期望没有意义。

方程式比较显然:

E[i]=∑k=1mpk∗(E[to(i,k)]+k)E[i]=\sum_{k=1}^mp_k*(E[to(i,k)]+k)E[i]=k=1∑m​pk​∗(E[to(i,k)]+k)

(to(i,k)to(i,k)to(i,k)表示iii点走kkk步到的点)

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 205;
const double eps = 1e-8; struct node {
int x, y;
node(){}
node(int x, int y):x(x), y(y){}
}b[MAXN]; double p[MAXN], a[MAXN][MAXN];
bool vis[MAXN]; inline bool gauss(int n) {
for(int j = 1; j <= n; ++j) {
if(!vis[j]) continue;
if(!a[j][j]) {
for(int i = j+1; i <= n; ++i)
if(a[i][j]) {
for(int k = j; k <= n+1; ++k)
swap(a[i][k], a[j][k]);
break;
}
}
if(fabs(a[j][j]) < eps) return 0;
for(int i = j+1; i <= n; ++i) if(vis[i]) {
double v = a[i][j] / a[j][j];
for(int k = j; k <= n+1; ++k)
a[i][k] -= v * a[j][k];
}
}
for(int i = n; i >= 1; --i) if(vis[i]) {
for(int j = i+1; j <= n; ++j) if(vis[j])
a[i][n+1] -= a[j][n+1] * a[i][j];
a[i][n+1] /= a[i][i];
}
return 1;
} int n, m, Y, X, D, cnt, id[MAXN][2], to[MAXN][MAXN]; queue<int>q;
inline bool bfs() {
memset(vis, 0, sizeof vis);
vis[id[X][D]] = 1;
q.push(id[X][D]);
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = 1; i <= m; ++i)
if(p[i] > eps && !vis[to[u][i]])
vis[to[u][i]] = 1, q.push(to[u][i]);
}
return vis[id[Y][0]] | vis[id[Y][1]];
} int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d%d%d%d", &n, &m, &Y, &X, &D); ++X, ++Y;
if(D == -1) D = X == 1;
else D ^= 1;
//0 -> leftwards
//1 -> rightwards for(int i = 1; i <= m; ++i) scanf("%lf", &p[i]), p[i] /= 100.0;
cnt = 0;
id[1][0] = id[1][1] = ++cnt; b[cnt] = node(1, 1);
id[n][0] = id[n][1] = ++cnt; b[cnt] = node(n, 0);
for(int i = 2; i < n; ++i)
id[i][0] = ++cnt, b[cnt] = node(i, 0),
id[i][1] = ++cnt, b[cnt] = node(i, 1); for(int i = 1; i <= cnt; ++i) {
node t = b[i];
t.x += t.y ? 1 : -1;
if(t.x == 1 || t.x == n) t.y ^= 1;
to[i][1] = id[t.x][t.y];
}
for(int j = 2; j <= m; ++j)
for(int i = 1; i <= cnt; ++i)
to[i][j] = to[to[i][j-1]][1];
if(!bfs()) puts("Impossible !");
else {
memset(a, 0, sizeof a);
for(int i = 1; i <= cnt; ++i) {
a[i][i] = 1;
if(!vis[i] || i == id[Y][0] || i == id[Y][1]) continue;
for(int j = 1; j <= m; ++j)
a[i][to[i][j]] -= p[j],
a[i][cnt+1] += p[j] * j;
}
if(!gauss(cnt)) puts("Impossible !");
double ans = a[id[X][D]][cnt+1];
printf("%.2f\n", ans);
}
}
}

Time travel HDU - 4418 (概率DP)的更多相关文章

  1. HDU 4599 概率DP

    先推出F(n)的公式: 设dp[i]为已经投出连续i个相同的点数平均还要都多少次才能到达目标状态. 则有递推式dp[i] = 1/6*(1+dp[i+1]) + 5/6*(1+dp[1]).考虑当前这 ...

  2. HDU 5001 概率DP || 记忆化搜索

    2014 ACM/ICPC Asia Regional Anshan Online 给N个点,M条边组成的图,每一步能够从一个点走到相邻任一点,概率同样,问D步后没走到过每一个点的概率 概率DP  測 ...

  3. hdu 3853 概率dp

    题意:在一个R*C的迷宫里,一个人在最左上角,出口在右下角,在每个格子上,该人有几率向下,向右或者不动,求到出口的期望 现在对概率dp有了更清楚的认识了 设dp[i][j]表示(i,j)到(R,C)需 ...

  4. HDU 4815 概率dp,背包

    Little Tiger vs. Deep Monkey Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K ( ...

  5. hdu 4050(概率dp)

    算是挺简单的一道概率dp了,如果做了前面的聪聪于可可的话,这题不需要什么预处理,直接概率dp就行了... #include <stdio.h> #include <stdlib.h& ...

  6. HDU 4405 (概率DP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4405 题目大意:飞行棋.如果格子不是飞行点,扔骰子前进.否则直接飞到目标点.每个格子是唯一的飞行起点 ...

  7. hdu 4336 概率dp + 状压

    hdu 4336 小吃包装袋里面有随机赠送一些有趣的卡片,如今你想收集齐 N 张卡片.每张卡片在食品包装袋里出现的概率是p[i] ( Σp[i] <= 1 ), 问你收集全部卡片所需购买的食品数 ...

  8. hdu 5001(概率DP)

    Walk Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  9. hdu 4576(概率dp+滚动数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4576 思路:由于每次从某一位置到达另一位置的概率为0.5,因此我们用dp[i][j]表示第i次操作落在 ...

随机推荐

  1. c# 中对于每次修改的程序 都必须重新手动生成 才能编译的问题

    问题描述:原来用VS2017,升级了VS2019,发现修改了Winform界面,F5运行竟然还是原来的界面 问题解决: 需要修改两个地方 工具>> 选项>> 项目和解决方案&g ...

  2. C++:盾神与条状项链

    实现代码如下: #include<cstdlib> #include <string> #include <iostream> using namespace st ...

  3. Python语言中各种进制相互转换

    目录 Python语言中各种进制相互转换 将二进制.八进制.十进制的数分别转换成十进制的方法 将十进制转换成二进制.八进制.十六进制 Python语言中各种进制相互转换 本文参考自https://ww ...

  4. java 用户线程和守护线程

    在Java中通常有两种线程:用户线程和守护线程(也被称为服务线程)通过Thread.setDaemon(false)设置为用户线程通过Thread.setDaemon(true)设置为守护线程线程属性 ...

  5. Error:Could not find method google() for arguments [] on repository container

    Error:Could not find method google() for arguments [] on repository container. Consult IDE log for m ...

  6. Scratch 母鸡保护鸡蛋

    今天我们一起实现一个“母鸡保护鸡蛋”的小游戏 具体思路是这样滴: 1.鸡蛋会不断的从右往左移动: 2.当母鸡快碰到鸡蛋的时候,按下“空格键”让母鸡跳跃起来: 3.如果母鸡落下没碰到鸡蛋,加一分: 4. ...

  7. Destination高级特性

    一.组合队列 Composite Destinations 组合队列允许用一个虚拟的destination代表多个destinations.这样就可以通过composite destinations在 ...

  8. VBA算术运算符

    以下是VBA支持算术运算符. 假设变量A=5,变量B=10,那么 - 运算符 描述 示例 + 两个操作数相加 A + B = 15 - 两个操作数相减 A - B = -5 * 两个操作数相乘 A * ...

  9. css 关于"浮动边距加倍"及其解决方法-------解决方案是在这个div里面加上display:inline;

    写div代码的时候,经常发现明明宽度算得很准确,但是莫明其妙的会和计划的布局不太一样- -|||开始以为自己代码写的有问题,拼命找bug也一无所获,最后可能会稍微修改样式来达到想要的效果,但终究也是外 ...

  10. $.serializeArray()获取不到input的value值bug问题

    今天修改form表单,发现有好几个input值保存不上,上网搜索了一下是$.serializeArray()获取不到disabled的值.如果想要让input元素变为不可用,可以把input设为rea ...