leetcode每日一题(2020-06-03):837. 新21点

题目描述:
爱丽丝参与一个大致基于纸牌游戏 “21点” 规则的游戏,描述如下:
爱丽丝以 0 分开始,并在她的得分少于 K 分时抽取数字。 抽取时,她从 [1, W] 的范围中随机获得一个整数作为分数进行累计,其中 W 是整数。 每次抽取都是独立的,其结果具有相同的概率。
当爱丽丝获得不少于 K 分时,她就停止抽取数字。 爱丽丝的分数不超过 N 的概率是多少?

今日学习:
1.动态规划真的不好想

题解:dp[i]表示初始得分为i时,按要求抽卡得分不超过N的概率

var new21Game = function(N, K, W) {
    //最后一轮抽取是在得分小于K的情况下,最后得分在 (K - 1) + 1 ~ (K - 1) + W 中间
    //由于dp[i-1]要用到dp[K + W],所以初始化数组长度为K + W + 1
    const dp = new Array(K + W + 1).fill(0);
    //temp用来计算dp[K + W]
    let temp = 0;
    //初始化得分为K - 1时,下一次抽卡是否大于N的dp[i]
    for (i = K; i < K + W; i ++) {
        if (i <= N) {
            dp[i] = 1;
        }
        if (i !== K) {
            temp += dp[i];
        }
    }
    //dp[K] = (dp[K + 1] + dp[K + 2] + ··· + dp[K + W]) / W;
    //dp[K + W] = dp[K] * W - dp[K + 1] - dp[K + 2] - ··· -dp[K + W - 1];
    dp[K + W] = dp[K] * W - temp;
    //迭代计算出dp[0]
    //1---dp[i] = (dp[i + 1] + dp[i + 2] + ··· + dp[i + W]) / W;
    //2---dp[i + 1] = (dp[i + 2] + dp[i + 3] + ··· + dp[i + W + 1]) / W;
    //(1 - 2)---dp[i] = (dp[i + 1] * (W + 1) - dp[i + W + 1]) / W
    for (i = K - 1; i >= 0; i --) {
        dp[i] = ( dp[i + 1] * (W + 1) - dp[i + 1 + W]) / W;
    }
    return dp[0];
};
posted @ 2020-06-05 11:19  秋夜星空  阅读(134)  评论(0编辑  收藏  举报