BZOJ 1415
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 using namespace std; 6 const int Maxn=1010; 7 int t[Maxn],n,m,S,T,now,p[Maxn][Maxn],head[Maxn],dis[Maxn],u,v,cnt; 8 double f[Maxn][Maxn]; 9 struct EDGE 10 { 11 int to,next; 12 }edge[Maxn<<2]; 13 inline void Add(int u,int v) 14 {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;} 15 void Dfs(int u,int top) 16 { 17 for (int i=head[u];i!=-1;i=edge[i].next) 18 if (dis[edge[i].to]==-1 || dis[edge[i].to]>dis[u]+1 || (dis[edge[i].to]==dis[u]+1 && p[now][edge[i].to]>top)) 19 { 20 dis[edge[i].to]=dis[u]+1; 21 p[now][edge[i].to]=top; 22 Dfs(edge[i].to,top); 23 } 24 } 25 double F(int S,int T) 26 { 27 if (f[S][T]!=0) return f[S][T]; 28 if (S==T) return 0; 29 if (p[p[S][T]][T]==T || p[S][T]==T) return 1; 30 double res=0; 31 for (int i=head[T];i!=-1;i=edge[i].next) 32 res+=F(p[p[S][T]][T],edge[i].to); 33 res+=F(p[p[S][T]][T],T); 34 res/=(double)(t[T]+1.0); 35 res+=1; 36 return f[S][T]=res; 37 } 38 int main() 39 { 40 scanf("%d%d",&n,&m); 41 scanf("%d%d",&S,&T); 42 memset(head,-1,sizeof(head)); 43 for (int i=1;i<=m;i++) 44 { 45 scanf("%d%d",&u,&v); 46 Add(u,v),Add(v,u); 47 t[u]++; t[v]++; 48 } 49 50 for (int i=1;i<=n;i++) 51 { 52 memset(dis,-1,sizeof(dis)); 53 dis[i]=0; 54 for (int j=head[i];j!=-1;j=edge[j].next) 55 { 56 now=i; 57 dis[edge[j].to]=1; 58 Dfs(edge[j].to,edge[j].to); 59 } 60 for (int j=head[i];j!=-1;j=edge[j].next) p[i][edge[j].to]=edge[j].to; 61 } 62 printf("%.3lf ",F(S,T)); 63 return 0; 64 }
BZOJ 1419
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 const int Maxn=5010; 7 double f[3][Maxn]; 8 int R,B,cur; 9 inline double Max(double x,double y) {return x>y?x:y;} 10 int main() 11 { 12 scanf("%d%d",&R,&B); 13 for (int i=1;i<=R;i++) 14 { 15 cur^=1; 16 for (int j=0;j<=B;j++) 17 { 18 if (i==0) {f[cur][j]=0; continue;} 19 if (j==0) {f[cur][j]=f[cur^1][j]+1;continue;} 20 f[cur][j]=Max(0,(f[cur^1][j]+1.0)*((double)(i)/(double)(i+j))+(f[cur][j-1]-1.0)*((double)(j)/(double)(i+j))); 21 22 } 23 } 24 printf("%.6lf ",f[cur][B]-5e-7); 25 return 0; 26 }
算法合集之《浅析竞赛中一类数学期望问题的解决方法》中有对题目的讲解。
HDU 4405 期望貌似是倒着推的,F[i]=∑F[i+k](k=1~6) /6+1; 但因为又加了一步所以要加一。可以直接跳到的则期望是一样的。
1 #include <cstdio> 2 #include <cstring> 3 const int Maxn=100100; 4 int vis[Maxn],n,m,u,v; 5 double F[Maxn]; 6 int main() 7 { 8 while (scanf("%d%d",&n,&m)!=EOF) 9 { 10 if (n==0 && m==0) break; 11 memset(vis,-1,sizeof(vis)); 12 for (int i=1;i<=m;i++) scanf("%d%d",&u,&v),vis[u]=v; 13 memset(F,0,sizeof(F)); 14 for (int i=n-1;i>=0;i--) 15 if (vis[i]==-1) 16 { 17 for (int j=1;j<=6;j++) F[i]+=F[i+j]/6.0; 18 F[i]=F[i]+1; 19 } else 20 F[i]=F[vis[i]]; 21 printf("%.4lf ",F[0]); 22 } 23 return 0; 24 }
HDU 4089 至今还不是很清楚怎么退的。。
1 #include <cstdio> 2 const int Maxn=2010; 3 const double eps=1e-5; 4 double F[Maxn][Maxn],p1,p2,p3,p4,x[Maxn],z[Maxn]; 5 int n,m,k; 6 int main() 7 { 8 while (scanf("%d%d%d%lf%lf%lf%lf",&n,&m,&k,&p1,&p2,&p3,&p4)!=EOF) 9 { 10 if (p4<eps) {puts("0.00000");continue;} 11 double p21=p2/(1-p1),p31=p3/(1-p1),p41=p4/(1-p1); 12 F[1][1]=p4/(1-p2-p1); 13 for (int i=2;i<=n;i++) 14 { 15 x[1]=p21; z[1]=p41; 16 for (int j=2;j<=i;j++) 17 { 18 x[j]=x[j-1]*p21; 19 z[j]=p31*F[i-1][j-1]+p21*z[j-1]; 20 if (j<=k) z[j]+=p41; 21 } 22 F[i][i]=z[i]/(1-x[i]); 23 for (int j=1;j<i;j++) F[i][j]=x[j]*F[i][i]+z[j]; 24 } 25 printf("%.5lf ",F[n][m]); 26 } 27 return 0; 28 }
POJ 2096 一直末状态推终状态。
1 #include<cstdio> 2 const int Maxn=1010; 3 double F[Maxn][Maxn]; 4 int n,s; 5 int main() 6 { 7 while(scanf("%d%d",&n,&s)!=EOF) 8 { 9 F[n][s]=0; 10 for(int i=n;i>=0;i--) 11 for(int j=s;j>=0;j--) 12 { 13 if(i==n && j==s) continue; 14 F[i][j]=(i*(s-j)*F[i][j+1]+(n-i)*j*F[i+1][j]+(n-i)*(s-j)*F[i+1][j+1]+n*s)/(n*s-i*j); 15 } 16 printf("%.4f ",F[0][0]); 17 } 18 return 0; 19 }
POJ 3744 矩阵乘法加速线性表达式递推。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int Maxn=20; 6 struct Matrix {double a[3][3]; int x,y;}; 7 int n,a[Maxn]; 8 double p,Ans; 9 inline Matrix operator * (Matrix A,Matrix B) 10 { 11 Matrix C; C.x=A.x,C.y=B.y; 12 memset(C.a,0,sizeof(C.a)); 13 for (int i=1;i<=A.x;i++) 14 for (int j=1;j<=A.y;j++) 15 for (int k=1;k<=B.y;k++) 16 C.a[i][j]+=A.a[i][k]*B.a[k][j]; 17 return C; 18 } 19 inline Matrix Pow(Matrix x,int y) 20 { 21 22 Matrix Ret; Ret.x=2,Ret.y=2; 23 memset(Ret.a,0,sizeof(Ret.a)); 24 Ret.a[1][1]=Ret.a[2][2]=1; 25 26 while (true) 27 { 28 if (y&1) Ret=Ret*x; 29 x=x*x; y>>=1; 30 if (y==0) break; 31 } 32 return Ret; 33 } 34 35 double Get(int t) 36 { 37 if (t<=1) return 0; 38 if (t==2) return 1; 39 if (t==3) return p; 40 t-=3; 41 Matrix M; 42 M.x=M.y=2; 43 M.a[1][1]=p; 44 M.a[1][2]=1-p; 45 M.a[2][1]=1; 46 M.a[2][2]=0; 47 M=Pow(M,t); 48 return M.a[1][1]*p+M.a[1][2]; 49 } 50 51 int main() 52 { 53 while (scanf("%d%lf",&n,&p)!=EOF) 54 { 55 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 56 sort(a+1,a+n+1); 57 Ans=1; 58 for (int i=1;i<=n;i++) 59 Ans=Ans*Get(a[i]-a[i-1])*(1.0-p); 60 printf("%.7lf ",Ans); 61 } 62 return 0; 63 }
POJ 3071 直接DP即可
1 #include <cstdio> 2 #include <cstring> 3 double F[10][250],p[250][250]; 4 int n,Ans; 5 int main() 6 { 7 while (scanf("%d",&n)!=EOF) 8 { 9 if (n==-1) break; 10 memset(F,0,sizeof(F)); 11 for (int i=1;i<=(1<<n);i++) 12 for (int j=1;j<=(1<<n);j++) scanf("%lf",&p[i][j]); 13 for (int i=1;i<=(1<<n);i++) F[0][i]=1.0; 14 for (int i=1;i<=n;i++) 15 for (int j=1;j<=(1<<n);j++) 16 for (int k=1;k<=(1<<n);k++) 17 if (((j-1)>>(i-1)^1)==((k-1)>>i-1)) 18 F[i][j]+=F[i-1][j]*F[i-1][k]*p[j][k]; 19 double Ret=0; 20 for (int i=1;i<=(1<<n);i++) 21 if (F[n][i]>Ret) Ans=i,Ret=F[n][i]; 22 printf("%d ",Ans); 23 } 24 return 0; 25 }