传送门

题目大意:

一张无向图上有一只猫和一只老鼠,猫先走,鼠后走。猫每次会向与其相邻的并且距离老鼠最近的点移动(若距离相等去编号较小的),如果移动一步后还没吃到老鼠,还可以再移动一步(算在一个时间内的)。老鼠每次会向相邻的点移动或者不移动,所有选择的概率相同。问猫期望多少时间能够吃到老鼠。

题目分析:

期望dp:设\(f[i][j]\)表示猫在i点,鼠在j点,猫吃到鼠的期望步数。\(P[i][j]\)表示与i相邻的点中距离j最近且编号最小的点(bfs预处理)。\(deg[i]\)表示i的度数。

那么:$$f[i][j] = f[P[P[i][j]][j] / (deg[v] + 1) + \sum{f[P[P[i][j]][v_j] / (deg[v] + 1)} + 1$$

方程上面两式分别对应:

  1. 猫移动,鼠不移动。
  2. 猫移动,鼠移动。

    初始化:$$f[i][i] = 0$$

\[f[i][j] = 1(dis[i][j] \le 2)
\]

code

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 1050, M = 1050,OO = 0x3f3f3f3f;
  4. #define eps 1e-8
  5. int n, m, p, q, vt;
  6. int ecnt, adj[N], nxt[M << 1], go[M << 1], P[N][N], dist[N][N], deg[N];
  7. double f[N][N];
  8. int vst[N];
  9. struct node{
  10. int now, dis;
  11. node(){}
  12. node(int _now, int _dis):now(_now), dis(_dis){}
  13. };
  14. inline void addEdge(int u, int v){
  15. nxt[++ecnt] = adj[u], adj[u] = ecnt, go[ecnt] = v;
  16. deg[u]++;
  17. }
  18. inline void Bfs(int i){
  19. static queue<node> que;
  20. while(!que.empty()) que.pop();
  21. vt++;
  22. que.push(node(i, 0));
  23. vst[i] = vt;
  24. while(!que.empty()){
  25. node u = que.front(); que.pop();
  26. for(int e = adj[u.now]; e; e = nxt[e]){
  27. int v = go[e];
  28. if(vst[v] == vt) continue;
  29. dist[i][v] = u.dis + 1;
  30. vst[v] = vt;
  31. node ret = node(v, u.dis + 1);
  32. que.push(ret);
  33. }
  34. }
  35. }
  36. inline void init(){
  37. memset(dist, OO, sizeof dist);
  38. for(int i = 1; i <= n; i++) dist[i][i] = 0, Bfs(i);
  39. for(int i = 1; i <= n; i++){
  40. P[i][i] = i;
  41. for(int j = i + 1; j <= n; j++){
  42. /*与i相邻的与j最近的点*/
  43. int mndis = OO, point = 0;
  44. for(int e = adj[i]; e; e = nxt[e]){
  45. int v = go[e];
  46. if(dist[v][j] < mndis){
  47. mndis = dist[v][j];
  48. point = v;
  49. }
  50. else if(dist[v][j] == mndis && v < point) point = v;
  51. }
  52. P[i][j] = point;
  53. /*与j相邻的与i最近的点*/
  54. mndis = OO, point = 0;
  55. for(int e = adj[j]; e; e = nxt[e]){
  56. int v = go[e];
  57. if(dist[v][i] < mndis){
  58. mndis = dist[v][i];
  59. point = v;
  60. }
  61. else if(dist[v][i] == mndis && v < point) point = v;
  62. }
  63. P[j][i] = point;
  64. }
  65. }
  66. }
  67. inline double F(int u, int v){
  68. if(f[u][v] >= 0) return f[u][v];
  69. f[u][v] = 1.0;
  70. int to = P[P[u][v]][v];
  71. double p = 1.0 / (1.0*deg[v] + 1.0);
  72. f[u][v] += F(to, v) * p;
  73. for(int e = adj[v]; e; e = nxt[e]){
  74. int vj = go[e];
  75. f[u][v] += F(to, vj) * p;
  76. }
  77. return f[u][v];
  78. }
  79. int main(){
  80. freopen("h.in", "r", stdin);
  81. scanf("%d%d%d%d", &n, &m, &p, &q);
  82. for(int i = 1; i <= m; i++){
  83. int x, y;
  84. scanf("%d%d", &x, &y);
  85. addEdge(x, y), addEdge(y, x);
  86. }
  87. init();
  88. for(int i = 1; i <= n; i++)
  89. for(int j = 1; j <= n; j++)
  90. f[i][j] = -5555;
  91. for(int i = 1; i <= n; i++){
  92. f[i][i] = 0;
  93. for(int j = i + 1; j <= n; j++){
  94. if(dist[i][j] <= 2) f[i][j] = f[j][i] = 1.0;
  95. }
  96. }
  97. printf("%.3lf\n", F(p, q));
  98. }

BZOJ1415 聪聪与可可 - 期望dp的更多相关文章

  1. 【BZOJ】1415 [Noi2005]聪聪和可可 期望DP+记忆化搜索

    [题意]给定无向图,聪聪和可可各自位于一点,可可每单位时间随机向周围走一步或停留,聪聪每单位时间追两步(先走),问追到可可的期望时间.n<=1000. [算法]期望DP+记忆化搜索 [题解]首先 ...

  2. BZOJ 1415 聪聪和可可(期望DP)

    我们可以用n次BFS预处理出 to[][]数组,to[i][j]表示聪聪从i点到j点第一步会走哪个点. 那么对于聪聪在i点,可可在j点,聪聪先走,定义dp[i][j]表示步数期望. 那么显然有dp[i ...

  3. 洛谷4206/NOI2005T4 聪聪和可可 期望DP+记忆化搜索

    题意:给出n个点m条边的无向图,两个主角聪聪和可可开始分别在S点和T点.聪聪想吃掉可可,每次由匆匆先行动后来可可行动.聪聪的行动是选他到可可的最短路上的点走最多两步(如果最短路有几条就选编号最小的走) ...

  4. bzoj 1415: [Noi2005]聪聪和可可 期望dp+记忆化搜索

    期望dp水题~ 你发现每一次肯定是贪心走 2 步,(只走一步的话就可能出现环) 然后令 $f[i][j]$ 表示聪在 $i$,可在 $j$,且聪先手两个人碰上面的期望最小次数. 用记忆化搜索转移就行了 ...

  5. luogu P4206 [NOI2005]聪聪与可可 期望dp 记忆化搜索

    LINK:聪聪与可可 这道题的核心是 想到如何统计答案. 如果设f[i][j]表示第i个时刻... 可以发现还需要统计位置信息 以及上一次到底被抓到没有的东西 不太好做. 两者的位置都在变化 所以需要 ...

  6. [NOI2005]聪聪与可可(期望dp)

    题意:给一张无向图,有一只猫和一只老鼠,猫每秒会向老鼠的方向移动两个单位,若它们的距离为一,那么只会移动一个单位,老鼠会等概率向周围移动一步或不动,求猫抓到老鼠的期望时间. Solutionluogu ...

  7. BZOJ1415 [Noi2005]聪聪和可可 【SPFA + 期望dp记忆化搜索】

    题目 输入格式 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行 ...

  8. bzoj1415 [Noi2005]聪聪和可可【概率dp 数学期望】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1415 noip2016 D1T3,多么痛的领悟...看来要恶补一下与期望相关的东西了. 这是 ...

  9. 概率/期望DP初步——BZOJ1415 聪聪和可可

    期望相关: 数学期望,可以简单理解的加权平均数.设有一系列的值$x_i$,每个值被取到的概率为$p_i$,则期望$E=\sum\limits_{i=1}^n p_i x_i$. 期望具有线性性:$$E ...

随机推荐

  1. Android 开发之锁屏弹窗

    尝试利用 WindowManager 添加浮窗的方式实现 想在锁屏上面实现弹窗,第一个想法就是利用 WindowManager 设置 Window 的 Flag,通过设置 Flag 的显示优先级来让窗 ...

  2. 自定义HTML标签属性

    为HTML元素添加一自定义的属性非常方便,只须将其加到尖括号中即可,与内置属性地位相等. 如我们要为TextBox元素添加属性idvalue: <input type="text&qu ...

  3. TreeView 的简单实用

    TreeView组件是由多个类来定义的,TreeView组件是由命名空间"System.Windows.Forms"中的"TreeView"类来定义的,而其中的 ...

  4. ActiveX控件开发 C#

    转自:http://hi.baidu.com/charlesx_kst/item/9c2f42e2920db3f42b09a4ff 前言: 这段时间因为工作的需要,研究了一下ActiveX控件.总结如 ...

  5. [RxJS] Avoid mulit post requests by using shareReplay()

    With the shareReplay operator in place, we would no longer fall into the situation where we have acc ...

  6. 【几何/数学】概念的理解 —— (非)刚体变换((non-)rigid transformation)

    1. 刚体变换与非刚体变换 What is a non-rigid transformation? 刚体变换(rigid transformation)一般分为如下几种: 平移对象,而不改变形状和大小 ...

  7. windows下安装emscripten

    windows下安装emscripten windows下安装emscripten需要python.git环境 python安装 git安装 开始安装 # 1.克隆emsdk git clone ht ...

  8. FZU Problem 2062 Suneast & Yayamao

    http://acm.fzu.edu.cn/problem.php?pid=2062 题目大意: 给你一个数n,要求求出用多少个数字可以表示1~n的所有数. 思路: 分解为二进制. 对于一个数n,看它 ...

  9. python3 turtle 画围棋棋盘

    python3 环境 利用turtle模块画出 围棋棋盘 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan impor ...

  10. POJ 1163 The Triangle 简单DP

    看题传送门门:http://poj.org/problem?id=1163 困死了....QAQ 普通做法,从下往上,可得状态转移方程为: dp[i][j]= a[i][j] + max (dp[i+ ...