zoukankan      html  css  js  c++  java
  • poj 2096 , zoj 3329 , hdu 4035 —— 期望DP

    题目:http://poj.org/problem?id=2096

    题目好长...意思就是每次出现 x 和 y,问期望几次 x 集齐 n 种,y 集齐 s 种;

    所以设 f[i][j] 表示已经有几种,转移一下即可。

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef double db;
    int const xn=1005;
    int n,s; db f[xn][xn];
    int main()
    {
      scanf("%d%d",&n,&s);
      for(int i=n;i>=0;i--)
        for(int j=s;j>=0;j--)
          {
        if(i==n&&j==s)continue;
        db p0=1.0*i/n*j/s,p1=1.0*(n-i)/n*j/s,p2=1.0*i/n*(s-j)/s,p3=1.0*(n-i)/n*(s-j)/s;
        f[i][j]=p1*f[i+1][j]+p2*f[i][j+1]+p3*f[i+1][j+1]+1;
        f[i][j]=f[i][j]/(1-p0);
          }
      printf("%.6f
    ",f[0][0]);
      return 0;
    }
    View Code

    题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3754

    带环的期望DP,本来用高斯消元可以做,但 n^3 * T 过不了;

    发现每个状态都有到 f[0] 的转移,所以设 f[i] = A[i] * f[0] + B[i] (套路!)

    然后把递推式子代入一番,得到 A[i] 和 B[i] 的转移是无环的,求出 A[0], B[0] 即可。

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef double db;
    int rd()
    {
      int ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    int const xn=550;
    int n,f[xn]; db p[20],A[xn],B[xn];
    int main()
    {
      int T=rd();
      while(T--)
        {
          n=rd(); int k1=rd(),k2=rd(),k3=rd(),a=rd(),b=rd(),c=rd(),sum=k1+k2+k3;
          for(int i=0;i<=sum;i++)p[i]=0;
          p[0]=1.0/(k1*k2*k3);
          for(int i=1;i<=k1;i++)
        for(int j=1;j<=k2;j++)
          for(int k=1;k<=k3;k++)
            if(i!=a||j!=b||k!=c)p[i+j+k]+=p[0];
          for(int i=0;i<=n+sum;i++)A[i]=0,B[i]=0;
          for(int i=n;i>=0;i--)
        {
          for(int k=3;k<=sum;k++)
            A[i]+=p[k]*A[i+k],B[i]+=p[k]*B[i+k];
          A[i]+=p[0]; B[i]+=1;
        }
          printf("%.10f
    ",B[0]/(1-A[0]));
        }
      return 0;
    }
    View Code

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4035

    树上带环!同样可以高斯消元,但复杂度不行;

    设 ( f[x] ) 表示在 x 这个点距离结束的期望,( P[x] = 1 - K[x] - E[x] ),( d[x] ) 为度数,得到朴素方程:

    ( f[x] = K[x] * f[1] + frac{P[x]}{d[x]}(f[fa]+1) + frac{P[x]}{d[x]}sumlimits_{v in son}(f[v]+1) )

    由于转移的顺序实际上应该是从 ( fa ) 到 ( x ),又因为每个点都和 ( 1 ) 组成环(或者因为最后要求 ( f[1] ) ?),所以设 ( f[x] = A[x]f[1] + B[x]f[fa] + C[x] )

    于是可以树形DP得到 ( A[x], B[x], C[x] )

    ( f[1] = frac{C[1]}{1-A[1]} ),当 ( A[1] ) 趋近于 1 时无解;

    eps 设成 1e-8 会 WA,1e-10 才可以。

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define eps 1e-10
    using namespace std;
    typedef double db;
    int rd()
    {
      int ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    int const xn=10005;
    int n,hd[xn],ct,to[xn<<1],nxt[xn<<1],d[xn];
    db K[xn],E[xn],P[xn],A[xn],B[xn],C[xn];
    void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
    void dfs(int x,int fa)
    {
      db as=0,bs=0,cs=0;
      for(int i=hd[x],u;i;i=nxt[i])
        {
          if((u=to[i])==fa)continue;
          dfs(u,x);
          as+=A[u]; bs+=B[u]; cs+=C[u];
        }
      A[x]=(d[x]*K[x]+P[x]*as)/(d[x]-P[x]*bs);
      B[x]=P[x]/(d[x]-P[x]*bs);
      C[x]=(P[x]*cs+d[x]*P[x])/(d[x]-P[x]*bs);
    }
    int main()
    {
      int T=rd(),cnt=0;
      while(T--)
        {
          cnt++; n=rd(); ct=0; memset(hd,0,sizeof hd); memset(d,0,sizeof d);
          for(int i=1,x,y;i<n;i++)x=rd(),y=rd(),add(x,y),add(y,x),d[x]++,d[y]++;
          for(int i=1;i<=n;i++)
        scanf("%lf%lf",&K[i],&E[i]),K[i]/=100,E[i]/=100,P[i]=1-K[i]-E[i];
          for(int i=1;i<=n;i++)A[i]=B[i]=C[i]=0;
          dfs(1,0);
          printf("Case %d: ",cnt);
          if(fabs(A[1]-1)<eps)puts("impossible");
          else printf("%.8f
    ",C[1]/(1-A[1]));
        }
      return 0;
    }
    View Code
  • 相关阅读:
    Android webView 缓存 Cache + HTML5离线功能 解决
    android 退出系统
    WebView简介(加速加载篇)
    android 处理Back键按下事件
    android 极细线
    [cnblog新闻]历史性时刻:云硬件支出首次高于传统硬件
    Oracle ORDS的简单SQL配置模板
    [cnbeta]华为值多少钱,全世界非上市公司中估值最高的巨头
    其他数据库的restful方式
    [CB]2018全球半导体营收4700亿美元 三星继续碾压英特尔
  • 原文地址:https://www.cnblogs.com/Zinn/p/10278561.html
Copyright © 2011-2022 走看看