【期望DP】LightOJ 1030 - Discovering Gold

 LightOJ 1030 - Discovering Gold

题意:在一个1*N的图中。起始点在1,掷骰子,下一个位置为当前位置+掷出的骰子点数。每个格子有各自的黄金数量。必须要走到最后一个格子N,如果距离小于6并且掷出的点数超出了N,那么可以多次掷骰子,直到下一个位置在范围内为止。

思路:期望DP模板。

期望DP:

离散期望=值*概率 的和

必须从后往前推期望值。因为前边的期望会影响后面的期望,推到最后会造成期望值的偏大。而到达最后一个格子是唯一的,不会有影响它的事件。所以我们倒着往前推,最后的结果是dp[1].

就这个题来讲:

我们拿样例3来说:

dp[3] = 9;
dp[2] = 6 + dp[3] * 1;//从格子2开始,到达格子3的概率为1
dp[1] = 3 + dp[2]/2 + dp[3]/2;//从格子1开始,到达格子2、3的概率为1/2

就是因为我们最后一步一定是最后一个格子,所以最后长度小于6的时候概率也发生了变化 

 

先求和后乘概率是错的!!!!!!!!!QAQ我WA了,要每一步都要dp[ ]*P才AC了www

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <limits>
#include <set>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#define INF 0x3f3f3f3f

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 100 + 5;
int n;
double v[maxN];
double dp[maxN];

int main()
{
    int T_T; scanf("%d", &T_T);
    for(int Case = 1; Case <= T_T; Case ++ )
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++ )
        {
            scanf("%lf", &v[i]);
        }
        for(int i = n; i > 0; i -- )
        {
            dp[i] = v[i];
            int len = n - i;
            if(len > 6)
                len = 6;
            double sum = 0;
            for(int cnt = 1; cnt <= len; cnt ++ )
                dp[i] += dp[cnt + i] / (double)len;
                //sum += dp[cnt + i];
            //dp[i] += sum / (double)len;
        }
        printf("Case %d: %f\n", Case, dp[1]);
    }
    return 0;
}
发布了180 篇原创文章 · 获赞 54 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/103864811