Open azl397985856 opened 1 year ago
class Solution: def new21Game(self, n: int, k: int, maxPts: int) -> float: dp = collections.deque([float(i <= n) for i in range(k, k + maxPts)]) s = sum(dp) for i in range(k): dp.appendleft(s / maxPts) s += dp[0] - dp.pop()
return dp[0]
动态规划,从后向前,依次计算概率(因为前面的牌面依赖后面的点数概率)
时间复杂度:O(k+maxPts) 空间复杂度:O(k+maxPts)
class Solution:
def new21Game(self, n: int, k: int, maxPts: int) -> float:
dp=[0]*(k+maxPts)
s = 0 # 右边maxpts张牌的概率累积
for i in range(k,k+maxPts):
dp[i] = 1 if i<=n else 0
s += dp[i]
for i in range(k-1,-1,-1):
dp[i]=1/maxPts*s
s = s - dp[i+maxPts] + dp[i]
return dp[0]
class Solution {
public:
double new21Game(int n, int k, int maxPts) {
if (k == 0) {
return 1.0;
}
vector<double> dp(k + maxPts);
for (int i = k; i <= n && i < k + maxPts; i++) {
dp[i] = 1.0;
}
dp[k - 1] = 1.0 * min(n - k + 1, maxPts) / maxPts;
for (int i = k - 2; i >= 0; i--) {
dp[i] = dp[i + 1] - (dp[i + maxPts + 1] - dp[i + 1]) / maxPts;
}
return dp[0];
}
};
滑动窗口+动态规划
(看了官方题解)
class Solution:
def new21Game(self, n: int, k: int, maxPts: int) -> float:
dp = [0] * (k + maxPts)
win_sum = 0
for i in range(k, k + maxPts):
if i <= n:
dp[i] = 1
win_sum += dp[i]
for i in range(k - 1, -1, -1):
dp[i] = win_sum / maxPts
win_sum += dp[i] - dp[i + maxPts]
return dp[0]
T(n) = O(w+k)
S(n) = O(w+k)
class Solution:
def new21Game(self, n: int, k: int, maxPts: int) -> float:
dp = [0 for i in range(k)] + [1 for i in range(k, 1 + n)] + [0 for i in range(maxPts)]
Win = float(sum(dp[k : k + maxPts]))
for i in range(k-1,-1,-1):
dp[i] = Win / maxPts
Win += dp[i] - dp[i + maxPts]
return dp[0]
class Solution:
def new21Game(self, N: int, K: int, W: int) -> float:
# 滑动窗口优化(固定窗口大小为 W 的滑动窗口)
dp = [0] * (K + W)
win_sum = 0
for i in range(K, K + W):
if i <= N:
dp[i] = 1
win_sum += dp[i]
for i in range(K - 1, -1, -1):
dp[i] = win_sum / W
win_sum += dp[i] - dp[i + W]
return dp[0]
"""
二分法,从k-1的时候开始计算后续可能结果的概率,并进行累加
"""
class Solution:
def new21Game(self, n: int, k: int, maxPts: int) -> float:
dp = [0] * (k+maxPts)
s = 0
for i in range(k, k+maxPts):
dp[i] = 1 if i <= n else 0
s+=dp[i]
for i in range(k-1,-1,-1):
dp[i] = s/maxPts
s = s-dp[i+maxPts]+dp[i]
return dp[0]
"""
时间复杂度:O(k+maxPts)
空间复杂度:O(k+maxPts)
"""
class Solution:
def new21Game(self, n: int, k: int, maxPts: int) -> float:
dp = [0.0] * (k + maxPts)
for i in range(k, min(n + 1, k + maxPts)):
dp[i] = 1.0
s = min(n - k + 1,maxPts)
for j in range(k -1, -1, -1):
dp[j] = s/float(maxPts)
s += dp[j] - dp[j + maxPts]
return dp[0]
time, space: O(n+1)/O(k+maxPts), O(k + maxPts)
dp + huadongchuangkou
if k == 0 or n >= k + maxPts - 1:
return 1.0
dp = [0] * (n + 1)
weight = 1.0
response = 0.0
dp[0] = 1.0
for i in range(1, n + 1):
dp[i] = weight / maxPts
if i < k:
weight = weight + dp[i]
else:
response = response + dp[i]
if i - maxPts >= 0:
weight = weight - dp[i - maxPts]
return response
O(n)
class Solution:
def new21Game(self, n: int, k: int, maxPts: int) -> float:
if k == 0:
return 1.0
dp = [0.0] * (k + maxPts)
for i in range(k, min(n, k + maxPts - 1) + 1):
dp[i] = 1.0
dp[k - 1] = float(min(n - k + 1, maxPts)) / maxPts
for i in range(k - 2, -1, -1):
dp[i] = dp[i + 1] - (dp[i + maxPts + 1] - dp[i + 1]) / maxPts
return dp[0]
class Solution:
def new21Game(self, n: int, k: int, maxPts: int) -> float:
dp = [1 if i <= N else 0 for i in range(k + maxPts)]
s = sum(dp[k:(k + maxPts)])
for i in range(k - 1, -1, -1):
dp[i] = s / maxPts
s -= dp[i + maxPts] + dp[i]
return dp[0]
class Solution {
public:
double new21Game(int n, int k, int maxPts) {
if (k == 0)
{
return 1.0;
}
vector<double> dp(k + maxPts);
for (int i = k; i <= n && i < k + maxPts; i++)
{
dp[i] = 1.0;
}
dp[k - 1] = 1.0 * min(n - k + 1, maxPts) / maxPts;
for (int i = k - 2; i >= 0; i--)
{
dp[i] = dp[i + 1] - (dp[i + maxPts + 1] - dp[i + 1]) / maxPts;
}
return dp[0];
}
};
func new21Game(n int, k int, maxPts int) float64 {
dp := make([]float64, k + maxPts)
for i := k; i < k + maxPts; i++ {
if i <= n {
dp[i] = 1
} else {
dp[i] = 0
}
}
for i := k - 1; i >= 0; i-- {
var sum float64
for j := i + 1; j <= i + maxPts; j++ {
sum += dp[j]
}
dp[i] = sum / float64(maxPts)
}
return dp[0]
}
func new21Game(n int, k int, maxPts int) float64 {
dp := make([]float64, k + maxPts)
for i := k; i < k + maxPts; i++ {
if i <= n {
dp[i] = 1
} else {
dp[i] = 0
}
}
for i := k - 1; i >= 0; i-- {
var sum float64
for j := i + 1; j <= i + maxPts; j++ {
sum += dp[j]
}
dp[i] = sum / float64(maxPts)
}
return dp[0]
}
class Solution {
public double new21Game(int n, int k, int maxPts) {
if(k==0) return 1.00;
if(k==1 && maxPts<=n) return 1.00;
double dp[] = new double[n+1];
dp[0] = 1.00;
double prev=0.00;
for(int i=1; i<=n; i++){
if((i-maxPts-1)>=0){
prev-=dp[i-1-maxPts];
}
if((i-1)<k){
prev+=dp[i-1];
}
dp[i]=prev/maxPts;
}
double res = 0.00;
for(int i=k; i<=n; i++){
res+=dp[i];
}
return res;
}
}
/**
* @param {number} n
* @param {number} k
* @param {number} maxPts
* @return {number}
*/
var new21Game = function(n, k, maxPts) {
const dp = new Array(k + maxPts).fill(0);
let sum = 0;
for (let i = k; i <= n && i < k + maxPts; i++) {
dp[i] = 1;
sum++;
}
for (let i = k - 1; i >= 0; i--) {
dp[i] = sum / maxPts;
sum += dp[i] - dp[i + maxPts];
}
return dp[0];
};
TC: O(n+maxPts)
SC: O(n+maxPts)
public double new21Game(int n, int k, int maxPts) {
if (k == 0) return 1;
double[] dp = new double[k + maxPts];
double sum = 0;
for (int i = k; i < k + maxPts; i++) {
if (i <= n) dp[i] = 1;
sum += dp[i];
}
for (int i = k - 1; i >= 0; i--) {
dp[i] = sum / maxPts;
sum = sum - dp[i + maxPts] + dp[i];
}
return dp[0];
}
不是很懂dp。。 先抄一个。。一会儿写滑动窗口+二分
public double New21Game(int n, int k, int maxPts)
{
if (k == 0)
{
return 1.0;
}
double[] dp = new double[k + maxPts];
for (int i = k; i <= n && i < k + maxPts; i++)
{
dp[i] = 1.0;
}
dp[k - 1] = 1.0 * Math.Min(n - k + 1, maxPts) / maxPts;
for (int i = k - 2; i >= 0; i--)
{
dp[i] = dp[i + 1] - (dp[i + maxPts + 1] - dp[i + 1]) / maxPts;
}
return dp[0];
}
复杂度分析
待定
class Solution {
public:
double new21Game(int n, int k, int maxPts) {
if (k == 0 || n >= k + maxPts - 1) return 1.0;
vector<double> dp(n + 1);
dp[0] = 1.0;
double W = 1.0, res = 0.0;
for (int i = 1; i <= n; ++i) {
dp[i] = W / maxPts;
if (i < k) W += dp[i];
else res += dp[i];
if (i - maxPts >= 0) W -= dp[i - maxPts];
}
return res;
}
};
复杂度分析 待定
public double new21Game(int n, int k, int maxPts) {
if(k==0) return 1.00;
if(k==1 && maxPts<=n) return 1.00;
double dp[] = new double[n+1];
dp[0] = 1.00;
double prev=0.00;
for(int i=1; i<=n; i++){
if((i-maxPts-1)>=0){
prev-=dp[i-1-maxPts];
}
if((i-1)<k){
prev+=dp[i-1];
}
dp[i]=prev/maxPts;
}
double res = 0.00;
for(int i=k; i<=n; i++){
res+=dp[i];
}
return res;
}
class Solution:
def new21Game(self, N: int, K: int, W: int) -> float:
dp = [0] * (K + W)
win_sum = 0
for i in range(K, K + W):
if i <= N:
dp[i] = 1
win_sum += dp[i]
for i in range(K - 1, -1, -1):
dp[i] = win_sum / W
win_sum += dp[i] - dp[i + W]
return dp[0]
Python3 Code:
class Solution:
def new21Game(self, N: int, K: int, W: int) -> float:
# 滑动窗口优化(固定窗口大小为 W 的滑动窗口)
dp = [0] * (K + W)
win_sum = 0
for i in range(K, K + W):
if i <= N:
dp[i] = 1
win_sum += dp[i]
for i in range(K - 1, -1, -1):
dp[i] = win_sum / W
win_sum += dp[i] - dp[i + W]
return dp[0]
复杂度分析
令 n 为数组长度。
class Solution {
public double new21Game(int n, int k, int maxPts) {
if (k == 0) {
return 1.0;
}
double[] dp = new double[k + maxPts];
for (int i = k; i <= n && i < k + maxPts; i++) {
dp[i] = 1.0;
}
dp[k - 1] = 1.0 * Math.min(n-k+1, maxPts) / maxPts;
for (int i = k - 2; i >= 0; i--) {
dp[i] = dp[i + 1] - (dp[i+maxPts+1] - dp[i + 1]) / maxPts;
}
return dp[0];
}
}
复杂度分析
class Solution:
def new21Game(self, N: int, K: int, W: int) -> float:
dp = [0] * (K + W)
for i in range(K, K + W):
if i <= N:
dp[i] = 1
for i in range(K - 1, -1, -1):
dp[i] = sum(dp[i + j] for j in range(1, W + 1)) / W
return dp[0]
复杂度分析
滑动窗口、动态规划
class Solution:
def new21Game(self, n: int, k: int, maxPts: int) -> float:
if k == 0:
return 1.0
dp = [0.0] * (k + maxPts)
for i in range(k, min(n, k + maxPts - 1) + 1):
dp[i] = 1.0
dp[k - 1] = float(min(n - k + 1, maxPts)) / maxPts
for i in range(k - 2, -1, -1):
dp[i] = dp[i + 1] - (dp[i + maxPts + 1] - dp[i + 1]) / maxPts
return dp[0]
class Solution { public double new21Game(int N, int K, int W) { if (K == 0 || N >= K + W) return 1; double dp[] = new double[N + 1], Wsum = 1, res = 0; dp[0] = 1; for (int i = 1; i <= N; ++i) { dp[i] = Wsum / W; if (i < K) Wsum += dp[i]; else res += dp[i]; if (i - W >= 0) Wsum -= dp[i - W]; } return res; } }
class Solution {
public:
double new21Game(int n, int k, int maxPts) {
if (k == 0) {
return 1.0;
}
vector<double> dp(k + maxPts);
for (int i = k; i <= n && i < k + maxPts; i++) {
dp[i] = 1.0;
}
dp[k - 1] = 1.0 * min(n - k + 1, maxPts) / maxPts;
for (int i = k - 2; i >= 0; i--) {
dp[i] = dp[i + 1] - (dp[i + maxPts + 1] - dp[i + 1]) / maxPts;
}
return dp[0];
}
};
class Solution(object): def new21Game(self, N, K, W):
if K == 0: return 1
dp = [1.0] + [0] * N
tSum = 1.0
for i in range(1, N + 1):
dp[i] = tSum / W
if i < K:
tSum += dp[i]
if 0 <= i - W < K:
tSum -= dp[i - W]
return sum(dp[K:])
class Solution {
public double new21Game(int n, int k, int maxPts) {
if (n-k + 1 >= maxPts) {
return 1.0;
}
double[] dp = new double[k+maxPts];
double sum = n-k+1;
for(int i=k; i<=n; i++){
dp[i] =1;
}
for(int i=k-1; i>=0; i--){
dp[i] = sum / (maxPts);
sum = sum - dp[i+maxPts]+ dp[i];
}
return dp[0];
}
}
class Solution {
public:
double new21Game(int N, int K, int W) {
if (K == 0) return 1.0;
vector<double> f(N + 1, 0), s(N + 1, 0);
f[0] = s[0] = 1;
for (int i = 1; i <= N; i++) {
int l = max(0, i - W), r = min(K - 1, i - 1);
if (l <= r) {
if (l == 0) f[i] = s[r] / W;
else f[i] = (s[r] - s[l - 1]) / W;
}
s[i] = s[i - 1] + f[i];
}
return s[N] - s[K - 1];
}
};
var new21Game = function (n, k, w) {
const dp = new Array(k + w).fill(0)
for (let i = k; i <= Math.min(n, k - 1 + w); i++) {
dp[i] = 1
}
for (let i = k - 1; i >= 0; i--) {
sum = 0
for (let j = 1; j <= w; j++) {
sum += dp[i + j]
}
dp[i] = sum / w
}
return dp[0]
};
蒙特卡洛模拟(超时,图一乐)
import random
class Solution:
def new21Game(self, n: int, k: int, maxPts: int) -> float:
# get random bonus between [1, maxPts]
def get_random_bonus(maxPts, sample_size):
return [random.randint(1, maxPts) for _ in range(sample_size)]
# 获得 k 分 或更多分时,停止抽取数字
def get_indicator(points, k):
return [point<k for point in points]
def Monte_Carlo(points, maxPts, k, epochs, sample_size):
for _ in range(epochs):
bonus = get_random_bonus(maxPts, sample_size)
indicators = get_indicator(points, k)
if sum(indicators)==0: return points
points = [b*i+p for (b, i, p) in zip(bonus, indicators, points)]
return points
epochs = 100000
sample_size = 100000
points = [0]*sample_size # init points
points = Monte_Carlo(points, maxPts, k, epochs, sample_size)
# 分数不超过 n 的概率
return sum([point<=n for point in points]) / sample_size
function new21Game(n: number, k: number, maxPts: number): number {
let dp = new Array(k + maxPts).fill(0);
dp[n] = 1;
for (let i = n - 1; i >= 0; i--) {
if (i >= k && i <= n) {
dp[i] = 1;
}
if (i < k) {
for (let j = 1; j <= maxPts; j++) {
if (i + j <= n) {
dp[i] += dp[i + j] / maxPts;
}
}
}
}
return dp[0];
}
动态规划
class Solution {
public double new21Game(int n, int k, int maxPts) {
if (k == 0) {
return 1.0;
}
double[] dp = new double[k + maxPts];
for (int i = k; i <= n && i < k + maxPts; i++) {
dp[i] = 1.0;
}
for (int i = k - 1; i >= 0; i--) {
for (int j = 1; j <= maxPts; j++) {
dp[i] += dp[i + j] / maxPts;
}
}
return dp[0];
}
}
837. 新 21 点
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/new-21-game
前置知识
暂无
题目描述