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
  • 相关阅读:
    013.ES6 -对象字面量增强型写法
    012. ES6
    011. ES6 语法
    10. 9. Vue 计算属性的setter和getter 以及 计算属性的缓存讲解
    4. Spring MVC 数据响应方式
    3. SpringMVC 组件解析
    9. Vue 计算属性
    【洛谷 2984】给巧克力
    【洛谷 1821】捉迷藏 Hide and Seek
    【洛谷 1821】银牛派对Silver Cow Party
  • 原文地址:https://www.cnblogs.com/Zinn/p/10278561.html
Copyright © 2011-2022 走看看