leetcode.837 新21點

837. 新21點

愛麗絲參與一個大致基於紙牌遊戲 “21點” 規則的遊戲,描述如下:

愛麗絲以 0 分開始,並在她的得分少於 K 分時抽取數字。 抽取時,她從 [1, W] 的範圍中隨機獲得一個整數作爲分數進行累計,其中 W 是整數。 每次抽取都是獨立的,其結果具有相同的概率。

當愛麗絲獲得不少於 K 分時,她就停止抽取數字。 愛麗絲的分數不超過 N 的概率是多少?

示例 1

輸入:N = 10, K = 1, W = 10
輸出:1.00000
說明:愛麗絲得到一張卡,然後停止。

示例 2

輸入:N = 6, K = 1, W = 10
輸出:0.60000
說明:愛麗絲得到一張卡,然後停止。
在 W = 10 的 6 種可能下,她的得分不超過 N = 6 分。

示例 3

輸入:N = 21, K = 17, W = 10
輸出:0.73278

提示:

  1. 0 <= K <= N <= 10000
  2. 1 <= W <= 10000
  3. 如果答案與正確答案的誤差不超過 10^-5,則該答案將被視爲正確答案通過。
  4. 此問題的判斷限制時間已經減少。

這道題真的就有點難

 說一下解題思路
 /*
 * 例如N=3,K=2,W=3 我們要求的實際是 i=[1,2,3]中,i=2的概率+i=3的概率
 * 我們可以從頭開始推,當手中沒有牌時,你抽到1的概率是 1/3也就是dp[1]=1/w
 * 當i=2時的方法有兩種: 手中牌是0, 你直接抽到2 這時概率是 A=1/3=1/w
 *                                        手中牌是1, 你抽到1 這時的概率是 B=1/3*1/3=(1/w)*(1/w) 這裏用的是條件概率的算法
 * 最終 dp[2]=A+B 
 * 因爲當i<=w的時候,你是可以直接抽到一張牌符合結果的
 * 所以,當i<=w的時候 dp[1]=1/w,dp[2]=dp[1]*1/w+1/w,dp[3]=dp[1]*1/w+dp[2]*1/w+1/w ... dp[i] = sum(dp[1,i-1])/w+1/w                         
 * 當i>w的時候沒有辦法取一次得到結果,所以不用加上1/w了,例如:N=6,K=4,W=2
 * 當i=3時,有2種取法1+2,2+1 沒有辦法從0直接到3,也就沒有1/w了
 *   dp[1]=1/w,dp[2]=dp[1]/w+1/w,dp[3]=sum(dp[1,2])/w
 * 當i=4時有兩種取法2+2,3+1   , dp[4]=sum(dp[2,3])/w=(sum(dp[1,3])-dp[1])/w=(sum(dp[w+1,i])-dp[i-w])/w
 * 因爲i的最大值是N所以dp的長度就是N+1
 * 最終解爲sum(dp[K,N])
 * 而當N >=(K + W)時 所有種k和w的和都不會超出N所以解是 1
 */

 

#include <iostream>

using namespace std;

double new21Game(int N, int K, int W) {

	int i;
	double dp[10002];
	double sum = 0;
	dp[0] = 1;
	if(K > 0){
		sum = sum + 1;
	}
	for(i = 1; i <= N; i++){
		dp[i] = sum / W;
		if(i < K){
			sum += dp[i];
		}
		if(i >= W){
			sum -= dp[i - W];
		}
	}
	double ans = 0;
	for(i = K; i <= N; i++){
		ans += dp[i];
	}
	return ans;

}


int main(){
	double re = new21Game(21, 17, 10);
	cout << re << endl;
}






 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章