1. 题目描述
一个人沿着一条长度为n个链行走,给出了每秒钟由i到j的概率($i,j \in [1,n]$)。求从1开始走到n个时间的期望。

2. 基本思路
显然是个DP。公式推导也相当容易。不妨设$dp[i], i \in [1,n]$表示由i到n的期望时间。
\begin{align}
    dp[i] &= \Sigma_{j=1}^{n} p(i, j) (dp[j] + 1),    &j<n\\
    dp[i] &= 0 &i=n
\end{align}
显然这是一个n元方程组,可以高斯消元解。但是因为n很大,因此不能直接套用高斯消元。但是通过观察系数矩阵可以发现规律。
以$n=7, m=2$为例,$\times$表示$A_{ij}$不为0。

发现每个行向量最多包含$2m+1$个非零向量,即$[i-m, i+m]$。因此,在高斯消元的过程中,实际每次需要减掉的系数最多也就$2m+1$个。
因为$m \in [1,5]$,可以直接模拟非零系数的消元。因为$i-m$有可能小于0,因此,将$[i-m,i+m]$映射到$[0,2m]$的区间内,$A_{ii}$恰好映射到$P_{im}$。
最后可以生成几个小规模的n,与高斯消元对拍一下。

3. 代码

  1. /* 4579 */
  2. #include <iostream>
  3. #include <sstream>
  4. #include <string>
  5. #include <map>
  6. #include <queue>
  7. #include <set>
  8. #include <stack>
  9. #include <vector>
  10. #include <deque>
  11. #include <algorithm>
  12. #include <cstdio>
  13. #include <cmath>
  14. #include <ctime>
  15. #include <cstring>
  16. #include <climits>
  17. #include <cctype>
  18. #include <cassert>
  19. #include <functional>
  20. #include <iterator>
  21. #include <iomanip>
  22. using namespace std;
  23. //#pragma comment(linker,"/STACK:102400000,1024000")
  24.  
  25. #define sti set<int>
  26. #define stpii set<pair<int, int> >
  27. #define mpii map<int,int>
  28. #define vi vector<int>
  29. #define pii pair<int,int>
  30. #define vpii vector<pair<int,int> >
  31. #define rep(i, a, n) for (int i=a;i<n;++i)
  32. #define per(i, a, n) for (int i=n-1;i>=a;--i)
  33. #define clr clear
  34. #define pb push_back
  35. #define mp make_pair
  36. #define fir first
  37. #define sec second
  38. #define all(x) (x).begin(),(x).end()
  39. #define SZ(x) ((int)(x).size())
  40. #define lson l, mid, rt<<1
  41. #define rson mid+1, r, rt<<1|1
  42.  
  43. const double eps = 1e-;
  44. const int maxn = ;
  45. const int maxm = ;
  46. double g[maxn][maxm], p[maxn][maxm];
  47. double v[maxn], x[maxn];
  48. int C[maxn][];
  49. int n, m;
  50.  
  51. void solve() {
  52. int i, j, k;
  53.  
  54. memset(p, , sizeof(p));
  55. for (i=; i<n; ++i) {
  56. int tot = ;
  57. double tmp = 0.0;
  58. for (j=; j<=m; ++j)
  59. tot += C[i][j];
  60.  
  61. for (j=; j<=m; ++j) {
  62. if (i-j >= ) {
  63. p[i][m-j] = 0.3 * C[i][j] / tot;
  64. tmp += p[i][m-j];
  65. }
  66. if (i+j <= n) {
  67. p[i][m+j] = 0.7 * C[i][j] / tot;
  68. tmp += p[i][m+j];
  69. }
  70. }
  71. p[i][m] = -tmp;
  72. v[i] = -;
  73. }
  74. p[n][m] = ;
  75. v[n] = ;
  76.  
  77. memcpy(g[], p[], sizeof(p[]));
  78. for (i=,k=; i<=n; ++i,++k) {
  79. int l = max(k-m, );
  80. int r = min(k+m, n);
  81. for (j=i; j<=n&&j-k<=m; ++j) {
  82. if (fabs(p[k][m]) < eps)
  83. continue;
  84. double t = p[j][k-j+m] / p[k][m];
  85. for (int kk=k+; kk<=n&&kk-k<=m; ++kk)
  86. p[j][kk-j+m] -= t * p[k][kk-k+m];
  87. v[j] -= t * v[k];
  88. }
  89.  
  90. l = max(i-m, );
  91. r = min(i+m, n);
  92. for (j=l; j<=r; ++j)
  93. g[i][j-i+m] = p[i][j-i+m];
  94. }
  95.  
  96. x[n] = ;
  97. for (i=n-,k=n; i>; --i,--k){
  98. for (j=i; j>&&k-j<=m; --j)
  99. v[j] -= x[k] * g[j][k-j+m];
  100. x[i] = v[i] / g[i][m];
  101. }
  102.  
  103. printf("%.2lf\n", x[]);
  104. }
  105.  
  106. int main() {
  107. ios::sync_with_stdio(false);
  108. #ifndef ONLINE_JUDGE
  109. freopen("data.in", "r", stdin);
  110. freopen("data.out", "w", stdout);
  111. #endif
  112.  
  113. while (scanf("%d%d",&n,&m)!=EOF && (n||m)) {
  114. rep(i, , n+)
  115. rep(j, , m+)
  116. scanf("%d", &C[i][j]);
  117. solve();
  118. }
  119.  
  120. #ifndef ONLINE_JUDGE
  121. printf("time = %d.\n", (int)clock());
  122. #endif
  123.  
  124. return ;
  125. }

4. 数据生成器

  1. import sys
  2. import string
  3. from random import randint
  4.  
  5. def GenData(fileName):
  6. with open(fileName, "w") as fout:
  7. t = 10
  8. for tt in xrange(t):
  9. n = randint(1, 200)
  10. m = randint(1, 5)
  11. fout.write("%d %d\n" % (n, m))
  12. L = [0] * m
  13. for i in xrange(n):
  14. for j in xrange(m):
  15. L[j] = randint(1, 9)
  16. fout.write(" ".join(map(str, L)) + "\n")
  17. fout.write("0 0\n")
  18.  
  19. def MovData(srcFileName, desFileName):
  20. with open(srcFileName, "r") as fin:
  21. lines = fin.readlines()
  22. with open(desFileName, "w") as fout:
  23. fout.write("".join(lines))
  24.  
  25. def CompData():
  26. print "comp"
  27. srcFileName = "F:\Qt_prj\hdoj\data.out"
  28. desFileName = "F:\workspace\cpp_hdoj\data.out"
  29. srcLines = []
  30. desLines = []
  31. with open(srcFileName, "r") as fin:
  32. srcLines = fin.readlines()
  33. with open(desFileName, "r") as fin:
  34. desLines = fin.readlines()
  35. n = min(len(srcLines), len(desLines))-1
  36. for i in xrange(n):
  37. ans2 = int(desLines[i])
  38. ans1 = int(srcLines[i])
  39. if ans1 > ans2:
  40. print "%d: wrong" % i
  41.  
  42. if __name__ == "__main__":
  43. srcFileName = "F:\Qt_prj\hdoj\data.in"
  44. desFileName = "F:\workspace\cpp_hdoj\data.in"
  45. GenData(srcFileName)
  46. MovData(srcFileName, desFileName)

【HDOJ】4579 Random Walk的更多相关文章

  1. 【BZOJ3470】Freda’s Walk 概率与期望

    [BZOJ3470]Freda’s Walk Description 雨后的Poetic Island空气格外清新,于是Freda和Rainbow出来散步. Poetic Island的交通可以看作一 ...

  2. HDU 4579 Random Walk (解方程组)

    Random Walk Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)Total ...

  3. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  4. 【HDOJ】5632 Rikka with Array

    1. 题目描述$A[i]$表示二级制表示的$i$的数字之和.求$1 \le i < j \le n$并且$A[i]>A[j]$的$(i,j)$的总对数. 2. 基本思路$n \le 10^ ...

  5. 【HDOJ】4418 Time travel

    1. 题目描述K沿着$0,1,2,\cdots,n-1,n-2,n-3,\cdots,1,$的循环节不断地访问$[0, n-1]$个时光结点.某时刻,时光机故障,这导致K必须持续访问时间结点.故障发生 ...

  6. 【HDOJ】4305 Lightning

    1. 题目描述当一个结点lightning后,可以向其周围距离小于等于R的结点传播lightning.然后以该结点为中心继续传播.以此类推,问最终形成的树形结构有多少个. 2. 基本思路生成树级数模板 ...

  7. 【HDOJ】4373 Mysterious For

    1. 题目描述有两种不同类型的循环,并给出一个由1.2组成的序列,表示嵌套的循环类型.问这样组着的循环一共需要多少次循环?并将结果模364875103. 2.基本思路显然,每当遇到一个类型1的序列,即 ...

  8. 【HDOJ】1667 The Rotation Game

    1. 题目描述有个#字型的条带,可以从横线或竖线进行循环移动,求通过各种移动最终使中心的8个字符全等的长度最短并相同长度字典序最小的操作序列.2. 基本思路24个数据,8种移动方式,数据量很小了,所以 ...

  9. 【HDOJ】4374 One hundred layer

    线性DP,使用单调队列优化. /* 4374 */ #include <iostream> #include <sstream> #include <string> ...

随机推荐

  1. SQL行列转换:报表_公司采购表_每个公司各采购了些什么产品

    有同学问了个比较典型行列转换的问题,想想,解答如下:数据库有一张表: 是个公司采购表,想转化成如下报表,显示每个公司各采购了些什么产品: 哪些公司采购哪些产品是不确定的,所以报表的列有哪几项是不确定的 ...

  2. Python Generators vs Iterators

    http://stackoverflow.com/questions/2776829/difference-between-python-generators-vs-iterators iterato ...

  3. [Linux]学习笔记(4)-su及passwd的用法介绍

    (1)su su命令用于将当前的用户切换到一个指定的用户.语法为: su - user_name 如果用户利用telnet方式远程登录,是不能直接以root账户登录的,也就是说在使用telnet登录服 ...

  4. web一次请求的流程

    1.客户端(浏览器输入网址)请求 2.发送http协议到web服务器(nginx),检测请求类别,如果时纯静态页面,则返响应返回给客户端. 3.如果有动态脚本(php语法)启动fastcgi进程,用解 ...

  5. ASP.NET生命周期事件顺序

    普通页面运行规律 Page_PreInitPage_InitPage_InitCompletePage_PreLoadPage_LoadButton1事件触发!Page_LoadCompletePag ...

  6. hibernate的n+1问题

    下面选自<精通Hibernate:Java对象持久化技术详解>作者:孙卫琴 在Session的缓存中存放的是相互关联的对象图.默认情况下,当Hibernate从数据库中加载Customer ...

  7. MVC5 Bundles发布到IIS失效问题解决方案

    MVC中Bundles可以提高代码的可重用性 我每个页面都需要用到这十几个JS+CSS 当我把MVC发布到服务器以后,Bundles中的JS和CSS会失效的时候 宝宝的心里是崩溃的.... 查了很多资 ...

  8. MVC学习系列——参考

    C#进阶系列——WebApi接口传参不再困惑:传参详解 http://www.cnblogs.com/landeanfen/p/5337072.html

  9. EXTJS 4.2 资料 控件之btn设置可否点击

    1.下面是一个btn按钮的代码,默认不可以点击 { id: 'skipStep3', disabled: true,//默认不可点击 text: "跳转第三步", handler: ...

  10. 原创新闻 11 个最佳 jQuery 滚动条插件

    通过jQuery滚动条插件,你可以换掉千篇一律的默认浏览器滚动条,让你的网站或web项目更具特色,更有吸引力.本文收集了11款非常漂亮.实用的jQuery滚动条插件,你可以轻松将它们应用在自己的网站中 ...