• 期望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++
  • 相关阅读:
    创建类以及引用一个类
    修改hosts文件
    微信第三方登录接口开发
    Android定位
    Leetcode 102. Binary Tree Level Order Traversal
    Leetcode 725. Split Linked List in Parts
    Leetcode 445. Add Two Numbers II
    Leetcode 328. Odd Even Linked List
    Leetcode 237. Delete Node in a Linked List
    Leetcode 234. Palindrome Linked List
  • 原文地址:https://www.cnblogs.com/yyjxx2010xyu/p/5484111.html
Copyright © 2020-2023  润新知