① 題目描述
有一些不規則的硬幣。在這些硬幣中,表示第枚硬幣正面朝上的概率(從1起)。
請對每一枚硬幣拋擲一次,然後返回正面朝上的硬幣數等於的概率。
② 問題求解
誤區:這題容易被排列組合的想法先入爲主,其實這是一個動態規劃的問題。
1 動態方程
記爲拋第個硬幣時恰好有個朝上的概率,則:
反向迭代可以去除的維度,將空間優化爲:
其中,爲恰有個硬幣朝上的概率。
2 代碼求解
"""
思路:
動態規劃 res[x]指的是恰好x個爲正的概率
@See 動態規劃 https://leetcode-cn.com/tag/dynamic-programming/
樣例輸入:
prob = [0.4], target = 1
prob = [0.5,0.5,0.5,0.5,0.5], target = 0
樣例輸出:
0.4000
0.03125
"""
from typing import List
class Solution:
def cal_probability(self, prob: List[float], target: int) -> float:
res = [0 for _ in range(len(prob) + 1)]
res[0] = 1.0
for i in range(1, len(prob)+1):
for j in range(min(i, target), -1, -1):
# 恰好j個爲正 = 上一輪更新中j個正面的情況下第i個恰好爲反 + 已經j-1個正面的情況下第i個繼續爲正
res[j] = (res[j] * (1 - prob[i - 1])) + ((res[j - 1] * prob[i - 1]) if j > 0 else 0)
return res[target]