• LightOJ 1030 Discovering Gold (期望)


    https://vjudge.net/problem/LightOJ-1030

    题意:

    在一个1×N的格子里,每个格子都有相应的金币数,走到相应格子的话,就会得到该格子的金币。 
    现在从1格子开始,每次摇骰子,他就前进几步,但有一种情况例外,如果当前位置+色子数 > N,那么他就会重新摇色子。 
    走到N这个位置的话,意味着游戏结束了。 
    问游戏结束时,这个人得到金币的期望。

    思路:
    这里给出两种做法,一种是正序求解,一种是逆序求解。

    ①正序求解:

        这种做法是从前往后计算每个格子的概率,假设我们现在处于第i个格子,它后面还有k=min(n-i,6)个格子,那么通过这个格子,我们就可以到达它后面的格子,现在它后面第j(1<=j<=k)个格子的概率就要加上d[i] / k。仔细想一想的话,其实就是个全概率。自己不太能讲得清,具体还是看代码吧。

    ②逆序求解: 

        这种做法是从后往前计算,也就是概率dp。d[i]表示以i为起点的格子所能获得的期望。

        当我们要计算d[i]的时候,d[i]+=1/k*d[i+j]。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,int> pll;
    15 const int INF = 0x3f3f3f3f;
    16 const int maxn = 100 + 5;
    17 
    18 int n;
    19 
    20 int a[maxn];
    21 double r[maxn];
    22 
    23 int main()
    24 {
    25     //freopen("in.txt","r",stdin);
    26     int T;
    27     int kase=0;
    28     scanf("%d",&T);
    29     while(T--)
    30     {
    31         scanf("%d",&n);
    32         for(int i=1;i<=n;i++)  scanf("%d",&a[i]);
    33 
    34         memset(r,0,sizeof(r));
    35 
    36         r[1]=1;
    37         for(int i=1;i<=n;i++)
    38         {
    39             int k=6;
    40             while(i+k>n)  k--;
    41             for(int j=1;j<=k;j++)
    42             {
    43                 r[i+j]+=r[i]*(1.0/k);
    44             }
    45         }
    46 
    47         double ans=0;
    48         for(int i=1;i<=n;i++)
    49             ans+=r[i]*a[i];
    50 
    51         printf("Case %d: ",++kase);
    52         printf("%.7f
    ",ans);
    53     }
    54     return 0;
    55 }
    正序求解
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,int> pll;
    15 const int INF = 0x3f3f3f3f;
    16 const int maxn = 100 + 5;
    17 
    18 int n;
    19 
    20 double a[maxn];
    21 
    22 int main()
    23 {
    24     //freopen("in.txt","r",stdin);
    25     int T;
    26     int kase=0;
    27     scanf("%d",&T);
    28     while(T--)
    29     {
    30         scanf("%d",&n);
    31         for(int i=1;i<=n;i++)  scanf("%lf",&a[i]);
    32 
    33 
    34         for(int i=n-1;i>=1;i--)
    35         {
    36             int k=min(6,n-i);
    37             for(int j=1;j<=k;j++)
    38             {
    39                 a[i]+=1./k*a[i+j];
    40             }
    41         }
    42 
    43         printf("Case %d: ",++kase);
    44         printf("%.7f
    ",a[1]);
    45     }
    46     return 0;
    47 }
    逆序求解
  • 相关阅读:
    hdu 1873 看病要排队
    母函数详解
    【RDMA】无损网络和PFC(基于优先级的流量控制)
    图解Linux网络包接收过程
    结对编程 <==> 断背山?
    CMPP和SMPP协议比较
    Berkerly DB、SQL Server的性能比较
    使用Berkeley DB遇到问题了
    重新学习C语言
    超长短信的处理办法
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7228099.html
Copyright © 2020-2023  润新知