zoukankan      html  css  js  c++  java
  • Codeforces 1245 E. Hyakugoku and Ladders

    传送门

    显然这个图是个 $DAG$ ,那么就可以考虑跑 $dp$ 了

    先考虑没有梯子的情况,首先把每个位置标号,越后面的位置编号越小,终点位置编号为 $1$

    那么从终点往起点 $dp$ ,枚举当前位置摇到的数字,那么有 $f[x]=frac{sum_{i=1}^{6}(f[x-i]+1)}{6}$,并且 $f[1]=0$

    但是这是在 $x>6$ 的情况下成立的,因为如果 $x<=6$ 那么有可能不走,特殊考虑一下

    首先 $f[2]$ ,那么有 $5/6$ 的概率原地不动,$1/6$ 的概率走到终点,即 $f[2]=frac{5(f[2]+1)}{6}+frac{f[1]+1}{6}=(frac{5}{6}+frac{f[1]+1}{6}) / (1-5/6)$

    然后 $f[3]$ 也差不多考虑,$f[3]=frac{4(f[3]+1)}{6}+frac{f[1]+1}{6}+frac{f[2]+1}{6}=(frac{4}{6}+frac{f[1]+1}{6}+frac{f[2]+1}{6}) / (1-4/6)$

    发现对于 $xin [2,6]$ ,$f[x]=frac{(sum_{i=1}^{x-1}f[x-i]+1)/6+(7-i)/6}{1-(7-i)/6}$

    现在来考虑有梯子的情况,设位置 $x$ 有一个梯子通往位置 $y$ ,那么 $f[x]$ 转移的时候还要考虑瞬移到 $y$ 再走的情况

    差不多的转移,取个最小值即可,即和 $sum_{i=1}^{6}(f[y-i]+1)/6$ 取个最小值,对于 $y<=6$ 的情况同样要特殊处理

    看代码就知道具体怎么做了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    typedef double db;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int n=10,N=107;
    int id[N][N],to[N];
    db f[N];
    int main()
    {
        int tot=0;
        for(int i=1;i<=n;i++)
        {
            if(i&1)
                for(int j=1;j<=n;j++)
                    id[i][j]=++tot;
            else
                for(int j=n;j>=1;j--)
                    id[i][j]=++tot;
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                int a=read();
                if(a) to[id[i][j]]=id[i-a][j];
            }
        // f[2]=(f[2]+1)*5/6 + 1/6
        // f[3]=(f[3]+1)*4/6 + 1/6 + (f[2]+1)/6
        for(int i=2;i<=6;i++)
        {
            for(int j=1;j<i;j++)
                f[i]+=(f[i-j]+1.0)/6;
            f[i]+=(7.0-i)/6;
            f[i]/=(1.0-(7.0-i)/6);
        }
        for(int i=7;i<=tot;i++)
        {
            for(int j=1;j<=6;j++)
                f[i]+=(f[i-j]+1.0)/6;
            if(!to[i]) continue;
            db mi=0; int t=to[i];
            if(t==1) { f[i]=0; continue; }//我这个做法要特判
            for(int j=1;j<=6;j++)
                if(t-j>0) mi+=(f[t-j]+1.0)/6;
            if(t<=6) mi+=(7.0-t)/6,mi/=(1.0-(7.0-t)/6);
            f[i]=min(f[i],mi);
        }
        printf("%.10f
    ",f[tot]);
        return 0;
    }
  • 相关阅读:
    初认识AngularJS
    (imcomplete) UVa 10127 Ones
    UVa 10061 How many zero's and how many digits?
    UVa 11728 Alternate Task
    UVa 11490 Just Another Problem
    UVa 10673 Play with Floor and Ceil
    JSON对象和字符串的收发(JS客户端用typeof()进行判断非常重要)
    HTML.ActionLink 和 Url.Action 的区别
    EASYUI TREE得到当前节点数据的GETDATA方法
    jqueery easyui tree把已选中的节点数据拼成json或者数组(非常重要)
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11782276.html
Copyright © 2011-2022 走看看