[leetCode]837.新21点

在这里插入图片描述
这道题目需要用到动态规化,爱丽丝获胜的条件是得分x小于等于N。根据示例3,假设当前得分x为16,那么再抽一牌可能为[1-10]中的一张,其中抽到[1,5]时得分x<N,抽到[6,10]时得分大于N,因此
f ( 16 ) = 1 10 ∗ ( 1 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 ) = 0.5 f(16)=\frac {1}{10}*(1+1+1+1+1+0+0+0+0+0)=0.5 f(16)=101(1+1+1+1+1+0+0+0+0+0)=0.5
f ( x ) = 1 W ∗ ( f ( x + 1 ) + f ( x + 2 ) + f ( x + 3 ) + . . . + f ( x + W ) ) f(x)=\frac {1}{W}*(f(x+1)+f(x+2)+f(x+3)+...+f(x+W)) f(x)=W1(f(x+1)+f(x+2)+f(x+3)+...+f(x+W))
当x=15 时
f ( 15 ) = 1 10 ∗ 0.5 + 1 10 ∗ ( 1 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + 0 ) = 0.5 f(15)=\frac {1}{10}*0.5+\frac {1}{10}*(1+1+1+1+1+0+0+0+0)=0.5 f(15)=1010.5+101(1+1+1+1+1+0+0+0+0)=0.5
f ( x − 1 ) = 1 W ∗ ( f ( x ) + f ( x + 1 ) + f ( x + 2 + f ( x + 3 ) + . . . + f ( x + W − 1 ) ) f(x-1)=\frac {1}{W}*(f(x)+f(x+1)+f(x+2+f(x+3)+...+f(x+W-1)) f(x1)=W1(f(x)+f(x+1)+f(x+2+f(x+3)+...+f(x+W1))
所以就得到了转移方程f(x);
在这里插入图片描述

C++

class Solution {
public:
    double new21Game(int N, int K, int W) {
        if(K==0)return 1.0;
        vector<double> dp(N+W);//声明一个数组,用于保存得分为K情况下开始游戏,爱丽丝获胜的概率(分数不超过N)
        //先初始化dp;当K = 16 时,再抽一张牌能获得的最大分数为26最小分数为1,如果抽的为[1,5]爱丽丝获胜,抽的为[6,10]则失败
        //dp[17,26]为[1,1,1,1,1,0,0,0,0,0]
        for(int i = K; i < N+1; i++)//当N大于K+W时会出现out of range
            dp[i]=1.0;
        //从后往前计算dp[16]、dp[15]
        double tem = min(N-K+1,W);//tem表示后面10个概率相加最多只能为10
        for(int i = K - 1; i>=0; i--){
            dp[i]=tem/W;
            tem += dp[i]-dp[i+W];
        }
        return dp[0];    
    }
};
posted @ 2020-06-03 13:10  消灭猕猴桃  阅读(67)  评论(0编辑  收藏  举报