• 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;
    }
  • 相关阅读:
    Python中使用pip安装库时提示:远程主机强迫关闭了一个现有的连接
    一个真正有能力的人
    一个程序员的自白(延迟满足)
    小规模团队如何“微服务”管理
    一个程序员的自白(无知之者)
    小型系统如何“微服务”开发
    TCP协议学习总结(下)
    TCP协议学习总结(中)
    TCP协议学习总结(上)
    一个程序员的自白(三十而立)
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11782276.html
Copyright © 2020-2023  润新知