• [ZOJ 3329] One Person Game


    有三个分别有K1,K2,K3个面的骰子,每个面上的值为[1,Ki]

    设所投出的序列为{k1,k2,k3}

    当投出{a,b,c}时得分清零,否则得分增加k1+k2+k3

    求使得得分大于等于n的期望步数

    设dp[i]表示当前得分为i,达成目标所需的期望步数

    dp[i]=dp[i+k]*p[k]+dp[0]*p0+1

    其中p[i]表示使得分增加i的概率

    由于dp[i]与dp[0]有关,然而dp[0]未知,所以我们把dp[0]提出来

    则dp[i]=A[i]*dp[0]+B[i]

    带入原式得 

    dp[i]=(A[i+k]*dp[0]+B[i+k])*p[k]+dp[0]*p0+1

           =A[i+k]*dp[0]*p[k]+B[i+k]*p[k]+dp[0]*p0+1

           =dp[0]*(A[i+k]*p[k]+p0)+(B[i+k]*p[k]+1)

    所以A[i]=A[i+k]*p[k]+p0,B[i]=B[i+k]*p[k]+1

    边界:对于所有i>n,A[i]=B[i]=0

    ans=dp[0]=B[0]/(1-A[0])

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define maxn 600
     4 int T,n,K1,K2,K3,a,b,c;
     5 double p0,A[maxn],B[maxn],p[maxn];
     6 void PP(){
     7     memset(p,0,sizeof(p));
     8     p0=1.0/(K1*K2*K3);
     9     for(int i=1;i<=K1;i++)
    10         for(int j=1;j<=K2;j++)
    11             for(int k=1;k<=K3;k++){
    12                 if(i==a&&j==b&&k==c)continue;
    13                 p[i+j+k]+=p0;
    14             }
    15 }
    16 int main(){
    17     scanf("%d",&T);
    18     while(T--){
    19         scanf("%d",&n);
    20         scanf("%d%d%d",&K1,&K2,&K3);
    21         scanf("%d%d%d",&a,&b,&c);
    22         PP();
    23         memset(A,0,sizeof(A));
    24         memset(B,0,sizeof(B));
    25         for(int i=n;i>=0;i--){
    26             A[i]=p0,B[i]=1;
    27             for(int j=3;j<=K1+K2+K3;j++){
    28                 A[i]+=p[j]*A[i+j];
    29                 B[i]+=p[j]*B[i+j];
    30             }
    31         }
    32         printf("%.15lf
    ",B[0]/(1-A[0]));
    33     }
    34     return 0;
    35 }
    View Code
  • 相关阅读:
    Android studio界面相关设置
    HIVE和HBASE区别
    《梦断代码》经典语录--持续更新
    幽灵漏洞(Ghost gethost)
    服务化实战之 dubbo、dubbox、motan、thrift、grpc等RPC框架比较及选型
    thrift使用总结
    thrift学习总结
    IntelliJ IDEA配置Tomcat(完整版教程)
    sudo执行脚本找不到环境变量和命令
    W-TinyLFU——设计一个现代的缓存
  • 原文地址:https://www.cnblogs.com/Ngshily/p/5519556.html
Copyright © 2020-2023  润新知