Description
‘Snakes and Ladders’ or ‘Shap-Ludu’ is a game commonly played in Bangladesh. The game is so common that it would be tough to find a person who hasn’t played it. But those who haven’t played it (unlucky of course!) the rules are as follows.

1.There is a 10 x 10 board containing some cells numbered from 1 to 100.

2.You start at position 1.

3.Each time you throw a perfect dice containing numbers 1 to 6.

4.There are some snakes and some ladders in the board. Ladders will take you up from one cell to another. Snakes will take you down.

5.If you reach a cell that contains the bottom part of a ladder, you will immediately move to the cell which contains the upper side of that ladder. Similarly if you reach a cell that has a snake-head you immediately go down to the cell where the tail of that snake ends.

6.The board is designed so that from any cell you can jump at most once. (For example there is a snake from 62 to 19, assume that another is from 19 to 2. So, if you reach 62, you will first jump to 19, you will jump to 2. These kinds of cases will not be given)

7.There is no snake head in the 100-th cell and no ladder (bottom part) in the first cell.

8.If you reach cell 100, the game ends. But if you have to go outside the board in any time your move will be lost. That means you will not take that move and you have to throw the dice again.

Now given a board, you have to find the expected number of times you need to throw the dice to win the game. The cases will be given such that a result will be found.

Input
Input starts with an integer T (≤ 105), denoting the number of test cases.

The first line of a case is a blank line. The next line gives you an integer n denoting the number of snakes and ladders. Each of the next n lines contain two integers a and b (1 ≤ a, b ≤ 100, a ≠ b). If a < b, it means that there is a ladder which takes you from a to b. If a > b, it means that there is a snake which takes you from a to b. Assume that the given board follows the above restrictions.

Output
For each case of input, print the case number and the expected number of times you need to throw the dice. Errors less than 10-6 will be ignored.

Sample Input
2

14

4 42

9 30

16 8

14 77

32 12

37 58

47 26

48 73

62 19

70 89

71 67

80 98

87 24

96 76

0

Sample Output
Case 1: 31.54880806

Case 2: 33.0476190476

Main idea & Solution
给一个10 * 10 的矩阵,依次编号为1 ~ 100 , 你从1出发,要去终点100。
你只能通过两种方法转移,一种是掷骰子,掷到几就走几步;另一种是利用传送门,直接传送到另一个位置
现求从起点到终点需要掷骰子的期望次数

特别的,如果当前掷骰子后应该到的位置会超出100的边界,那这次作废,需要继续掷。

设dp[i]=dp[i] =dp[i]= 从点 iii 到 100 的期望次数,
① 有传送门:dp[i]=dp[to[i]]dp\left[ i\right] =dp\left[ to\left[ i\right] \right]dp[i]=dp[to[i]]
② 如果当前不可能会出界(i≤94i \leq 94i≤94) :dp[i]=16∑k=1k≤6dp[i+k]+1dp\left[ i\right] =\dfrac {1}{6}\sum ^{k\leq 6}_{k=1}dp\left[ i+k\right] +1dp[i]=61​∑k=1k≤6​dp[i+k]+1
③ 当前可能出界:dp[i]=16∑k=1i+k≤100dp[i+k]+16∑k=101k≤i+6dp[i]+1dp\left[ i\right] =\dfrac {1}{6}\sum ^{i+k\leq 100}_{k=1}dp\left[ i+k\right] +\dfrac {1}{6}\sum ^{k\leq i+6}_{k=101}dp\left[ i\right] +1dp[i]=61​∑k=1i+k≤100​dp[i+k]+61​∑k=101k≤i+6​dp[i]+1

因为有传送门,所以存在环状转移,故需要高斯消元

若某次将要出界,其实就是留在原地不动,本质上就是有1/6概率从自己的状态转移过来

Code

#include <bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;typedef long long ll;
const double eps = 1e-6;
int n = 100;
double m[110][110];
bool tp[110];
void build(){for(int i = 1;i < n;++i){if(tp[i]) continue;for(int k = 1;k <= 6;++k){if(k + i <= 100) m[i][i+k] = (-1.0 / 6);else m[i][i] -= 1.0 / 6;}m[i][i] += 1.0, m[i][n+1] = 1.0;}m[100][100] = 1.0, m[100][101] = 0.0;
}double ans[110];void gauss(){for(int i = 1;i <= n;++i){int r = i;for(int j = i + 1;j <= n;++j){if(fabs(m[r][i]) < fabs(m[j][i])) r = j;}if(i != r) swap(m[i],m[r]);double div = m[i][i];for(int j = i;j <= n + 1;++j) m[i][j] /= div;for(int j = i + 1;j <= n;++j){div = m[j][i];for(int k = i;k <= n + 1;++k){m[j][k] -= m[i][k] * div;}}}ans[n] = m[n][n+1];for(int i = n - 1;i >= 1;--i){ans[i] = m[i][n+1];for(int j = i + 1;j <= n;++j)ans[i] -= (m[i][j] * ans[j]);}
}void init(){clr(m,0);clr(ans,0);clr(tp,false);
}
int main(){int T,cas = 0;;scanf("%d",&T);while(T--){int q;scanf("%d",&q);for(int i = 1;i <= q;++i){int u,v;scanf("%d%d",&u,&v);tp[u] = true;m[u][u] = 1.0, m[u][v] = -1.0;}build();gauss();printf("Case %d: %.12f\n", ++cas,ans[1]);init();}
}

LightOJ 1151 Snakes and Ladders (期望DP + 高斯消元)相关推荐

  1. ICPC 2005 hangzhou Generator (UVA1358)KMP + 期望DP / 高斯消元

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Generator Weblink https://www.luogu.com.cn/problem/ ...

  2. P4457-[BJOI2018]治疗之雨【期望dp,高斯消元】

    正题 题目链接:https://www.luogu.com.cn/problem/P4457 题目大意 开始一个人最大生命值为nnn,剩余hphphp点生命,然后每个时刻如果生命值没有满那么有1m+1 ...

  3. 【BZOJ1778】[Usaco2010 Hol]Dotp 驱逐猪猡 期望DP+高斯消元

    [BZOJ1778][Usaco2010 Hol]Dotp 驱逐猪猡 Description 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300 ...

  4. 【BZOJ2337】XOR和路径,概率期望DP+高斯消元

    Time:2016.08.27 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 与游走思路有一定相似的地方 对答案的每一位进行判断 通过高斯消元解出每个点到n xor路径为1的概率 ...

  5. BZOJ 1778 Usaco2010 Hol Dotp 驱逐猪猡 期望DP+高斯消元

    题目大意:给定一个无向图,炸弹从1号节点出发,每个时刻有P/Q的概率爆炸,如果某个时刻没有爆炸,就会等概率沿着随机一条出边走到下一个城市,求最终每个城市的爆炸概率 #include <cmath ...

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

    [BZOJ3640]JC的小苹果 Description 让我们继续JC和DZY的故事. "你是我的小丫小苹果,怎么爱你都不嫌多!" "点亮我生命的火,火火火火火!&qu ...

  7. BZOJ 3270: 博物馆 1778: 驱逐猪猡 【概率DP+高斯消元】

    题目描述: 中文题面,不多解释.1778传送门 3270 传送门 (博物馆)题目分析: 也许很多人做概率题的时候都有种虚幻感..感觉莫名其妙就得出一个期望.概率,一知半解... 所以我在这里仔细地剖析 ...

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

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

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

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

最新文章

  1. 全面理解java内存模型_深入理解Java内存模型(八)——总结
  2. Nat. Methods | 学习微生物与代谢产物之间相互作用的神经网络
  3. 【跃迁之路】【732天】程序员高效学习方法论探索系列(实验阶段489-2019.2.22)...
  4. matlab 设置最大并行数_浅析线程池参数设置
  5. [JQuery代码]超酷鼠标滑过背景高亮效果
  6. mysql执行脚本的方法
  7. windows 2003 远程桌面无法使用剪贴板共享纯文本的解决方法(亲测可用)
  8. 从git repo分支安装pip
  9. python保留7天备份文件
  10. B00012 C++算法库的sort()函数
  11. 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(济南):签到题A Matrix Equation(高斯消元求线性异或方程组自由元个数)
  12. DPDK数据流过滤规则例程解析—— 网卡流处理功能窥探
  13. 四旋翼无人机飞控系统设计(姿态传感器MPU6050)
  14. 在线图片裁剪,关于使用cropperjs踩过的坑
  15. 自学Python 57 多线程开发(七)使用 Connection对象和共享对象 Shared
  16. uniapp的navigateTo页面跳转参数传递问题
  17. Devfreq Bus Dcvs
  18. 裸金属服务器内容讲解以及介绍
  19. GoogleAdMob广告 SDK接入(Android)
  20. DustBot机器人

热门文章

  1. Android Studio修改配置,释放C盘空间
  2. vmware操作linux,linux虚拟机初步 vmware的简单操作【鸟哥的私房菜第五章】
  3. Python+ChatGPT制作一个AI实用百宝箱
  4. 自动驾驶(五十七)---------车身航迹推算
  5. 【FeathersJS 入门】安装 Feathers
  6. Learning Deep Models for Face Anti-Spoofing_ Binary or Auxiliary Supervision
  7. HTTP 400 Problem accessng /xxx/xxx Reason:bad request Powered by jetty://
  8. 抖音账号你了解几种玩法以及实操揭秘
  9. deepin15.9.1 WIFI使用提速
  10. 全球最火的程序员学习路线!没有之一!3天就在Github收获了接近1w点赞