hdu 4579 Random Walk 概率DP

思路:由于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

 

 

 

你可能感兴趣的:(Random)