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

 

 

 

posted @ 2013-08-17 13:20  _随心所欲_  阅读(143)  评论(0编辑  收藏  举报