题目描述:
爱丽丝参与一个大致基于纸牌游戏 “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];
};