HDU 4579 Random Walk (解方程组)

Random Walk

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 81    Accepted Submission(s): 35

Problem Description Yuanfang is walking on a chain. The chain has n nodes numbered from 1 to n. Every second, he can move from node i to node j with probability:

c(i,j) is an element in a given parameter matrix which is n×m. (1 <= c(i, j) <= 9)

Yuanfang wants to know the expectation time for him to walk from node 1 to node n.  

 

Input There are no more than 10 test cases.

In each case, there are two integers n (2 <= n <= 50000), m (1 <= m <= 5), in the first line, meaning that there are n nodes and the parameter matrix is n×m . There are m integers in each of the next n lines which describe the parameter matrix .

The input ends with 0 0.  

 

Output For each case, output the expectation time for Yuanfang to walk from node 1 to node n in one line. The answer should be rounded to 2 digits after decimal point.  

 

Sample Input 3 1 1 1 1 5 2 1 2 2 1 3 2 2 3 1 3 0 0  

 

Sample Output 6.94 8.75  

 

Source
2013ACM-ICPC杭州赛区全国邀请赛           这题就是列出方程。   然后高斯消元解方程。   如果是一般的方程,高斯消元需要O(n*n)   但是这题的矩阵很特别     很快就可以消掉了。 用dp[i]表示i到n的期望。 dp[n]=0;     对于第i个方程,最多只有2*m+1个系数是不为0的。          

 1 /* **********************************************
 2 Author      : kuangbin
 3 Created Time: 2013/8/12 20:28:58
 4 File Name   : F:\2013ACM练习\比赛练习\2013杭州邀请赛重现\1004.cpp
 5 *********************************************** */
 6 
 7 #include <stdio.h>
 8 #include <string.h>
 9 #include <iostream>
10 #include <algorithm>
11 #include <vector>
12 #include <queue>
13 #include <set>
14 #include <map>
15 #include <string>
16 #include <math.h>
17 #include <stdlib.h>
18 using namespace std;
19 const int MAXN = 50010;
20 double c[MAXN][10];
21 double p[MAXN][20];
22 double a[MAXN][10];
23 double b[MAXN];
24 double dp[MAXN];
25 
26 int main()
27 {
28     //freopen("in.txt","r",stdin);
29     //freopen("out.txt","w",stdout);
30     int n,m;
31     while( scanf("%d%d",&n,&m) == 2 )
32     {
33         if(n == 0 && m == 0)break;
34         for(int i = 1;i <= n;i++)
35             for(int j = 1;j <= m;j++)
36                 scanf("%lf",&c[i][j]);
37         for(int i = 1;i < n;i++)
38         {
39             double sum = 0;
40             for(int j = 1;j <= m;j++)
41                 sum += c[i][j];
42             double s = 0;
43             for(int j = 1;j <= m && i-j >= 1;j++)
44             {
45                 p[i][m-j] = 0.3*c[i][j]/(1+sum);
46                 s += p[i][m-j];
47             }
48             for(int j = 1;j <= m && i+j <= n;j++)
49             {
50                 p[i][m+j] = 0.7*c[i][j]/(1+sum);
51                 s += p[i][m+j];
52             }
53             p[i][m] = -s;
54             b[i] = -1;
55         }
56         for(int i = 1;i <= m+1 && i <= n;i++)
57             a[1][i] = p[1][m+i-1];
58         for(int i = 2;i < n;i++)
59         {
60             int end = min(i+m,n);
61             int start = max(1,i-m);
62             
63             for(int j = start;j < i;j++)
64                 if(fabs(p[i][m+j-i]) > 1e-6)
65                 {
66                     double t = p[i][m+j-i]/a[j][1];
67                     for(int k = 1; k <= m+1 && j+k-1 <= n ;k++)
68                     {
69                         p[i][m+j-i+k-1] -= t*a[j][k];
70                     }
71                     b[i] -= t*b[j];
72                 }
73             for(int j = 1;j <= end-i+1;j++)
74                 a[i][j] = p[i][m+j-1];
75 
76         }
77         dp[n] = 0;
78         for(int i = n-1;i >= 1;i--)
79         {
80             for(int j = 2;j <= m+1 && i+j-1 <= n;j++)
81                 b[i] -= dp[i+j-1] * a[i][j];
82             dp[i] = b[i]/a[i][1];
83         }
84         printf("%.2f\n",dp[1]);
85     }
86     return 0;
87 }

 

                 

 

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/p/3254040.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞