zoukankan      html  css  js  c++  java
  • 期望DP

    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 }
    C++

    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 }
    C++

    算法合集之《浅析竞赛中一类数学期望问题的解决方法》中有对题目的讲解。

    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 }
    C++

    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 }
    C++

    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 }
    C++

    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 }
    C++

    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 }
    C++
  • 相关阅读:
    hdu 1142 用优先队列实现Dijkstra
    POJ 2063 Investment 完全背包
    POJ 3260 多重背包+完全背包
    bignum 大数模板
    POJ 3468(树状数组的威力)
    POJ 3468 线段树裸题
    hdu 1058 Humble Numbers
    CodeForces 185A 快速幂
    POJ 1990 MooFest 树状数组
    设计模式(20)策略模式
  • 原文地址:https://www.cnblogs.com/yyjxx2010xyu/p/5484111.html
Copyright © 2011-2022 走看看