• ZOJ 3329 One Person Game


    期望,$dp$。

    设$dp[i]$为目前和为$i$,到达目标状态需要的期望次数。$dp[i]=sum(dp[i+j]*p[j])+dp[0]/(k1*k2*k3)+1$。

    无奈,接下来不知所措。去高斯消元了,妥妥的超时......

    最终看了大佬博客。发现有一个骚操作。

    设$dp[i]=A[i]*dp[0]+B[i]$,如果知道$A[i]$与$B[i]$,那么$dp[0]=B[0]/(1-A[0])$。

    $dp[i+j]=A[i+j]*dp[0]+B[i+j]$。

    $dp[i]=sum(A[i+j]*dp[0]*p[j]+B[i+j]*p[j])+dp[0]/(k1*k2*k3)+1$。

    所以,$A[i]=sum(A[i+j]*p[j])+p[0]$,$B[i]=sum(B[i+j]*p[j])+1$。

    $A$和$B$倒着推一下就可以知道了。 真*智商捉急。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-6;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c = getchar();
        x = 0;
        while(!isdigit(c)) c = getchar();
        while(isdigit(c))
        {
            x = x * 10 + c - '0';
            c = getchar();
        }
    }
    
    int T,n,k1,k2,k3,a,b,c;
    int f[20];
    double A[505],B[505];
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&a,&b,&c);
    
            memset(f,0,sizeof f);
            for(int i=1; i<=k1; i++)
                for(int j=1; j<=k2; j++)
                    for(int s=1; s<=k3; s++) f[i+j+s]++;
            f[a+b+c]--;
    
            for(int i=n;i>=0;i--)
            {
                A[i]=1.0/(k1*k2*k3);
                B[i]=1.0;
                for(int j=1;j<=k1+k2+k3;j++)
                {
                    if(i+j>n) break;
                    A[i]=A[i]+A[i+j]*f[j]/(k1*k2*k3);
                    B[i]=B[i]+B[i+j]*f[j]/(k1*k2*k3);
                }
            }
    
            printf("%.8f
    ",B[0]/(1-A[0]));
        }
        return 0;
    }
  • 相关阅读:
    论 IntStream 和 for 循环的速度
    单链线性表的基本操作--创建,插入,删除,查看,打印
    Android中的异步处理方式
    Kotlin 集合变换与序列
    Kotlin Lazy延迟初始化
    协程及Kotlin协程
    Java 注解
    Android 事件传递机制进阶
    Java 异常
    Java 多线程及线程间通信(Synchronized和Volatile关键字)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6298395.html
Copyright © 2020-2023  润新知