hdu 4418 Time travel 概率DP

高斯消元求期望!!

将n时间点构成2*(n-1)的环,每一点的期望值为dp[i]=dp[i+1]*p1+dp[i+2]*p2+……+dp[i+m]*pm+1.

这样就可以多个方程,利用高斯消元求解。

代码如下:

 

  1 #include<iostream>

  2 #include<stdio.h>

  3 #include<algorithm>

  4 #include<iomanip>

  5 #include<cmath>

  6 #include<cstring>

  7 #include<vector>

  8 #include<queue>

  9 #define MAX 200

 10 #define eps 1e-8

 11 using namespace std;

 12 double p[MAX],a[MAX][MAX],ans[MAX];

 13 int N,n,m,num[MAX],row,col,cnt;

 14 int gauss()

 15 {

 16     int k,i,j;

 17     for(i=0,j=0;i<row&&j<col;i++,j++){

 18         int m=i;

 19         for(k=i+1;k<row;k++)

 20             if(fabs(a[k][j])-fabs(a[m][j])>eps)

 21                 m=k;

 22         if(fabs(a[m][j])<eps) return 0;

 23         if(m!=i)

 24             for(k=0;k<=col;k++)

 25                 swap(a[i][k],a[m][k]);

 26         double aa=a[i][j];

 27         for(k=i+1;k<row;k++){

 28             double bb=a[k][j]/aa;

 29             for(int l=j;l<=col;l++){

 30                 a[k][l]-=bb*a[i][l];

 31             }

 32         }

 33     }

 34     for(i=col-1;i>=0;i--){

 35         for(j=i+1;j<col;j++)

 36             a[i][col]-=a[i][j]*ans[j];

 37         ans[i]=a[i][col]/a[i][i];

 38     }

 39     return 1;

 40 }

 41 void bfs(int s)

 42 {

 43     queue<int>q;

 44     memset(num,-1,sizeof(num));

 45     cnt=0;

 46     num[s]=cnt++;

 47     q.push(s);

 48     while(!q.empty()){

 49         int t=q.front();

 50         q.pop();

 51         for(int i=1;i<=m;i++){

 52             if(fabs(p[i])<eps) continue;

 53             int k=(i+t)%n;

 54             if(num[k]==-1){

 55                 num[k]=cnt++;

 56                 q.push(k);

 57             }

 58         }

 59     }

 60 }

 61 int main(){

 62     int t,i,j,x,y,d,tm,k;

 63     scanf("%d",&t);

 64     while(t--){

 65         scanf("%d%d%d%d%d",&N,&m,&y,&x,&d);

 66         for(i=1;i<=m;i++){

 67             scanf("%lf",&p[i]);

 68             p[i]/=100.0;

 69         }

 70         if(x==y){

 71             printf("0.00\n");

 72             continue;

 73         }

 74         n=2*N-2;

 75         if(d==1) x=n-x;

 76         bfs(x);

 77         if(num[y]==-1&&num[n-y]==-1){

 78             printf("Impossible !\n");

 79             continue;

 80         }

 81         memset(a,0,sizeof(a));

 82         memset(ans,0,sizeof(ans));

 83         row=col=cnt;

 84         for(i=0;i<n;i++)

 85         if(num[i]!=-1){

 86             a[num[i]][num[i]]=1;

 87             if(i==y||i==n-y){

 88                 ans[num[i]]=0;

 89                 continue;

 90             }

 91             for(j=1;j<=m;j++){

 92                 tm=(i+j)%n;

 93                 if(num[tm]!=-1){

 94                     a[num[i]][num[tm]]-=p[j];

 95                     a[num[i]][cnt]+=j*p[j];

 96                 }

 97             }

 98         }

 99         if(gauss()) printf("%.2lf\n",ans[num[x]]);

100         else printf("Impossible !\n");

101     }

102     return 0;

103 }
View Code

 

 

 

你可能感兴趣的:(time)