• LightOj 1030


    题目链接:http://lightoj.com/volume_showproblem.php?problem=1030

    题意:在一个1*n 的格子里,每个格子都有相应的金币数,走到相应格子的话,就会得到该格子的金币。 

    现在有一个人在1这个位置,手里有一颗骰子,骰子摇到几,他就前进几步,但如果当前位置+骰子数 > n,那么他就会重新摇色子一直到<=n为止。 
    走到n这个位置的话,意味着游戏结束了。
     问游戏结束时,这个人得到金币的期望。

    设dp[i]表示从i号格子出去的期望,所以dp[i]是和i后面的紧接着6个数有关, 那么 则有dp[i] = (dp[i+1]/6 + ... + dp[i+6]/6) + dp[i]。

    初始化dp[i] = 第i个格子的gold值。
     
    #include <cstring>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    using namespace std;
    #define N 105
    #define met(a, b) memset(a, b, sizeof(a))
    
    typedef long long LL;
    
    int main()
    {
        int T, t = 1, n;
        scanf("%d", &T);
        while(T--)
        {
            double dp[N];
            int a[N];
            met(dp, 0);
    
            scanf("%d", &n);
            for(int i=1; i<=n; i++)
                scanf("%d", &a[i]);
    
            dp[n] = a[n];
    
            for(int i=n-1; i>=1; i--)
            {
                dp[i] = a[i];
                int k = min(6, n-i);
                for(int j=1; j<=k; j++)
                    dp[i] += dp[i+j]/k;
            }
    
            printf("Case %d: %.6f
    ", t++, dp[1]);
        }
        return 0;
    }
    View Code
     
    还有就是可以先求出到达每个格子的概率dp[i],然后再乘上格子的金币数就是所求期望了;
    #include <cstring>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    using namespace std;
    #define N 105
    #define met(a, b) memset(a, b, sizeof(a))
    
    typedef long long LL;
    
    int main()
    {
        int T, t = 1, n;
        scanf("%d", &T);
        while(T--)
        {
            double dp[N];
            int a[N];
            met(dp, 0);
    
            scanf("%d", &n);
            for(int i=1; i<=n; i++)
                scanf("%d", &a[i]);
    
            dp[1] = 1.0;
    
            for(int i=1; i<=n; i++)
            {
                int k = min(6, n-i);
                for(int j=1; j<=k; j++)
                    dp[i+j] += dp[i]/k;
            }
            double ans = 0;
            for(int i=1; i<=n; i++)
                ans += a[i]*dp[i];
            printf("Case %d: %.6f
    ", t++, ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    设计模式笔记(22)状态模式(行为型)
    设计模式笔记(16)解释器模式(行为型)
    Lable和Literal控件的使用和区别
    设计模式笔记(15)命令模式(行为型)
    设计模式笔记(25)总结
    在JS方法中返回多个值的三种方法
    SQL 左外连接,右外连接,全连接,内连接
    面试集萃
    ASP.NET MVC如何使用Ajax的辅助方法
    ASP.NET MVC+EF框架+EasyUI实现权限管理(附源码)
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5754909.html
Copyright © 2020-2023  润新知