首页 > 技术文章 > hdu 4579 Random Walk 概率DP

xin-hua 2013-08-23 20:26 原文

思路:由于m非常小,只有5。所以用dp[i]表示从位置i出发到达n的期望步数。

 

那么dp[n] = 0

 

dp[i] = sigma(dp[i + j] * p (i , i + j)) + 1 .   (-m <= j <= m)

 

从高位向低位暴力消元,每次消去比他高的变量。

如 dp[i] = a1 * dp[i - 1] + a2 * dp[i - 2] …… am * dp[i - m]。

 

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<iomanip>
 5 #include<cmath>
 6 #include<cstring>
 7 #include<vector>
 8 #define ll __int64
 9 #define pi acos(-1.0)
10 #define MAX 50002
11 using namespace std;
12 double a[MAX][11],p[MAX][11],consts[MAX],q;
13 int c[MAX],cc,l[MAX],r[MAX];
14 int main(){
15     int n,m,i,j,k;
16     while(scanf("%d%d",&n,&m)&&(n+m)){
17         memset(a,0,sizeof(a));
18         for(i=1;i<=n;i++){
19             cc=1;
20             for(j=1;j<=m;j++){
21                 scanf("%d",&c[j]);
22                 cc+=c[j];
23             }
24             p[i][m]=1.0;
25             for(j=-m;j<0;j++){
26                 p[i][j+m]=0.3*c[-j]/cc;
27                 if(i+j>=1) p[i][m]-=p[i][j+m];
28             }
29             for(j=1;j<=m;j++){
30                 p[i][j+m]=0.7*c[j]/cc;
31                 if(i+j<=n) p[i][m]-=p[i][j+m];
32             }
33         }
34         for(i=n-1;i>=1;i--){
35             l[i]=max(1,i-m);//记录该方程的下界
36             r[i]=min(n,i+m);//记录该方程的上界
37             for(j=0;j<r[i]-l[i]+1;j++)
38                 a[i][j]=p[i][l[i]+j-i+m];
39             consts[i]=1.0;//记录常数
40             for(j=r[i];j>i;j--){//将比i高位的变量消去
41                 if(j==n) a[i][j-l[i]]=0;//dp[n]=0
42                 else{
43                     q=a[i][j-l[i]];
44                     if(fabs(q)<1e-8) continue;//从i到j的概率为0,不需计算
45                     for(k=0;k<j-l[j];k++)//将相应变量的系数相加
46                         a[i][k+l[j]-l[i]]+=a[j][k]*q;
47                     consts[i]+=consts[j]*q;//将常数项相加
48                 }
49             }
50             q=1.0-a[i][i-l[i]];
51             for(j=0;j<r[i]-l[i]+1;j++)
52                 a[i][j]/=q;
53             a[i][i-l[i]]=0;
54             consts[i]/=q;
55         }
56         printf("%.2lf\n",consts[1]);
57     }
58     return 0;
59 }
View Code

 

 

 

推荐阅读