Skip to content

Commit 7856f5e

Browse files
committed
feat: add solutions to lc problem: No.1230
No.1230.Toss Strange Coins
1 parent f148a12 commit 7856f5e

File tree

7 files changed

+348
-102
lines changed

7 files changed

+348
-102
lines changed

solution/1200-1299/1230.Toss Strange Coins/README.md

+152-39
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,24 @@
3939

4040
<!-- 这里可写通用的实现逻辑 -->
4141

42-
`0-1` 背包问题。
42+
**方法一:动态规划**
43+
44+
我们定义 $f[i][j]$ 表示前 $i$ 枚硬币中有 $j$ 枚正面朝上的概率,初始时 $f[0][0]=1$,答案即为 $f[n][target]$。
45+
46+
考虑 $f[i][j]$,其中 $i \geq 1$,如果当前硬币反面朝上,那么 $f[i][j] = (1 - p) \times f[i - 1][j]$;如果当前硬币正面朝上,并且 $j \gt 0$,那么 $f[i][j] = p \times f[i - 1][j - 1]$。因此状态转移方程为:
47+
48+
$$
49+
f[i][j] = \begin{cases}
50+
(1 - p) \times f[i - 1][j], & j = 0 \\
51+
(1 - p) \times f[i - 1][j] + p \times f[i - 1][j - 1], & j \gt 0
52+
\end{cases}
53+
$$
54+
55+
其中 $p$ 表示第 $i$ 枚硬币正面朝上的概率。
56+
57+
我们注意到,状态 $f[i][j]$ 只与状态 $f[i - 1][j]$ 和 $f[i - 1][j - 1]$ 有关,因此,我们可以将二维空间优化为一维空间。
58+
59+
时间复杂度 $O(n \times target)$,空间复杂度 $O(target)$。其中 $n$ 为硬币的数量。
4360

4461
<!-- tabs:start -->
4562

@@ -50,30 +67,28 @@
5067
```python
5168
class Solution:
5269
def probabilityOfHeads(self, prob: List[float], target: int) -> float:
53-
m = len(prob)
54-
dp = [[0] * (target + 1) for _ in range(m + 1)]
55-
dp[0][0] = 1
56-
for i in range(1, m + 1):
57-
for j in range(target + 1):
58-
dp[i][j] = dp[i - 1][j] * (1 - prob[i - 1])
59-
if j >= 1:
60-
dp[i][j] += dp[i - 1][j - 1] * prob[i - 1]
61-
return dp[-1][-1]
70+
n = len(prob)
71+
f = [[0] * (target + 1) for _ in range(n + 1)]
72+
f[0][0] = 1
73+
for i, p in enumerate(prob, 1):
74+
for j in range(min(i, target) + 1):
75+
f[i][j] = (1 - p) * f[i - 1][j]
76+
if j:
77+
f[i][j] += p * f[i - 1][j - 1]
78+
return f[n][target]
6279
```
6380

64-
空间优化:
65-
6681
```python
6782
class Solution:
6883
def probabilityOfHeads(self, prob: List[float], target: int) -> float:
69-
dp = [0] * (target + 1)
70-
dp[0] = 1
71-
for v in prob:
84+
f = [0] * (target + 1)
85+
f[0] = 1
86+
for p in prob:
7287
for j in range(target, -1, -1):
73-
dp[j] *= (1 - v)
74-
if j >= 1:
75-
dp[j] += dp[j - 1] * v
76-
return dp[-1]
88+
f[j] *= (1 - p)
89+
if j:
90+
f[j] += p * f[j - 1]
91+
return f[target]
7792
```
7893

7994
### **Java**
@@ -83,17 +98,36 @@ class Solution:
8398
```java
8499
class Solution {
85100
public double probabilityOfHeads(double[] prob, int target) {
86-
double[] dp = new double[target + 1];
87-
dp[0] = 1;
88-
for (double v : prob) {
101+
int n = prob.length;
102+
double[][] f = new double[n + 1][target + 1];
103+
f[0][0] = 1;
104+
for (int i = 1; i <= n; ++i) {
105+
for (int j = 0; j <= Math.min(i, target); ++j) {
106+
f[i][j] = (1 - prob[i - 1]) * f[i - 1][j];
107+
if (j > 0) {
108+
f[i][j] += prob[i - 1] * f[i - 1][j - 1];
109+
}
110+
}
111+
}
112+
return f[n][target];
113+
}
114+
}
115+
```
116+
117+
```java
118+
class Solution {
119+
public double probabilityOfHeads(double[] prob, int target) {
120+
double[] f = new double[target + 1];
121+
f[0] = 1;
122+
for (double p : prob) {
89123
for (int j = target; j >= 0; --j) {
90-
dp[j] *= (1 - v);
91-
if (j >= 1) {
92-
dp[j] += dp[j - 1] * v;
124+
f[j] *= (1 - p);
125+
if (j > 0) {
126+
f[j] += p * f[j - 1];
93127
}
94128
}
95129
}
96-
return dp[target];
130+
return f[target];
97131
}
98132
}
99133
```
@@ -104,15 +138,39 @@ class Solution {
104138
class Solution {
105139
public:
106140
double probabilityOfHeads(vector<double>& prob, int target) {
107-
vector<double> dp(target + 1);
108-
dp[0] = 1;
109-
for (auto v : prob) {
141+
int n = prob.size();
142+
double f[n + 1][target + 1];
143+
memset(f, 0, sizeof(f));
144+
f[0][0] = 1;
145+
for (int i = 1; i <= n; ++i) {
146+
for (int j = 0; j <= min(i, target); ++j) {
147+
f[i][j] = (1 - prob[i - 1]) * f[i - 1][j];
148+
if (j > 0) {
149+
f[i][j] += prob[i - 1] * f[i - 1][j - 1];
150+
}
151+
}
152+
}
153+
return f[n][target];
154+
}
155+
};
156+
```
157+
158+
```cpp
159+
class Solution {
160+
public:
161+
double probabilityOfHeads(vector<double>& prob, int target) {
162+
double f[target + 1];
163+
memset(f, 0, sizeof(f));
164+
f[0] = 1;
165+
for (double p : prob) {
110166
for (int j = target; j >= 0; --j) {
111-
dp[j] *= (1 - v);
112-
if (j >= 1) dp[j] += dp[j - 1] * v;
167+
f[j] *= (1 - p);
168+
if (j > 0) {
169+
f[j] += p * f[j - 1];
170+
}
113171
}
114172
}
115-
return dp[target];
173+
return f[target];
116174
}
117175
};
118176
```
@@ -121,17 +179,72 @@ public:
121179

122180
```go
123181
func probabilityOfHeads(prob []float64, target int) float64 {
124-
dp := make([]float64, target+1)
125-
dp[0] = 1
126-
for _, v := range prob {
182+
n := len(prob)
183+
f := make([][]float64, n+1)
184+
for i := range f {
185+
f[i] = make([]float64, target+1)
186+
}
187+
f[0][0] = 1
188+
for i := 1; i <= n; i++ {
189+
for j := 0; j <= i && j <= target; j++ {
190+
f[i][j] = (1 - prob[i-1]) * f[i-1][j]
191+
if j > 0 {
192+
f[i][j] += prob[i-1] * f[i-1][j-1]
193+
}
194+
}
195+
}
196+
return f[n][target]
197+
}
198+
```
199+
200+
```go
201+
func probabilityOfHeads(prob []float64, target int) float64 {
202+
f := make([]float64, target+1)
203+
f[0] = 1
204+
for _, p := range prob {
127205
for j := target; j >= 0; j-- {
128-
dp[j] *= (1 - v)
129-
if j >= 1 {
130-
dp[j] += dp[j-1] * v
206+
f[j] *= (1 - p)
207+
if j > 0 {
208+
f[j] += p * f[j-1]
131209
}
132210
}
133211
}
134-
return dp[target]
212+
return f[target]
213+
}
214+
```
215+
216+
### **TypeScript**
217+
218+
```ts
219+
function probabilityOfHeads(prob: number[], target: number): number {
220+
const n = prob.length;
221+
const f = new Array(n + 1).fill(0).map(() => new Array(target + 1).fill(0));
222+
f[0][0] = 1;
223+
for (let i = 1; i <= n; ++i) {
224+
for (let j = 0; j <= target; ++j) {
225+
f[i][j] = f[i - 1][j] * (1 - prob[i - 1]);
226+
if (j) {
227+
f[i][j] += f[i - 1][j - 1] * prob[i - 1];
228+
}
229+
}
230+
}
231+
return f[n][target];
232+
}
233+
```
234+
235+
```ts
236+
function probabilityOfHeads(prob: number[], target: number): number {
237+
const f = new Array(target + 1).fill(0);
238+
f[0] = 1;
239+
for (const p of prob) {
240+
for (let j = target; j >= 0; --j) {
241+
f[j] *= 1 - p;
242+
if (j > 0) {
243+
f[j] += f[j - 1] * p;
244+
}
245+
}
246+
}
247+
return f[target];
135248
}
136249
```
137250

0 commit comments

Comments
 (0)