2019/12/07 乐山师范学院程序设计大赛—G 新21点

问题 G: 新21点

时间限制: 1 Sec  内存限制: 128 MB

题目链接:http://acm.lsnu.edu.cn/oj/problem.php?id=2499

题目描述

玩家参与一个大致基于纸牌游戏 “21点” 规则的游戏,描述如下:

以 0 分开始,在得分少于 K 分时抽取数字。 抽取时,从 [1, W] 的范围中随机获得一个整数作为分数进行累计。 每次抽取都是独立的,其结果具有相同的概率。

当获得不少于 K 分时,就停止抽取数字。 求解分数不超过 N 的概率是多少?

输入

输入仅有一行,包括三个整数 N,K,W ( 0 <= K <= N <= 1000, 1 <= W <= 10000 ) 。

输出

输出一个浮点数,请保留 5 位小数,表示分数不超过 N 的概率。

样例:

样例输入
6 1 10

样例输出
0.60000

提示

如果答案与正确答案的误差不超过 10^{-5},则该答案将被视为正确答案通过。

思路:

        这是一道动态规划的题,说实话对这道题理解还不够,先附上赛后题解吧。

赛后题解:

/*
动态规划,dp[i] 表示分数为 i 的概率,dp[i] = (dp[i-1] + dp[i-2] + ... + dp[i-W]) / W,
每次计算dp[i] 不能真的去进行 W 次累加,分母不变,分子可以维护一个前缀和 s, 这样递推即为线性时间复杂度。
*/
# include <stdio.h>
# define MIN(x, y) (((x) < (y)) ? (x) : (y))
int main() {
    int n, k, w, i;
    double dp[100000] = {0.0}, s = 0;
    scanf("%d%d%d", &n, &k, &w);
    for (i = 0; i < k; i++) {
        if (i < w) {
          dp[i] = (s + MIN(n - k + 1, w - i)) / w;
        } else {
          dp[i] = s / w;
          s -= dp[i - w];
        }
        s += dp[i];
    }
    printf("%.5lf\n", dp[k - 1]);
    return 0;
}
发布了26 篇原创文章 · 获赞 1 · 访问量 435

猜你喜欢

转载自blog.csdn.net/qq_45309822/article/details/103501598