39
39
40
40
<!-- 这里可写通用的实现逻辑 -->
41
41
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$ 为硬币的数量。
43
60
44
61
<!-- tabs:start -->
45
62
50
67
``` python
51
68
class Solution :
52
69
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 ]
62
79
```
63
80
64
- 空间优化:
65
-
66
81
``` python
67
82
class Solution :
68
83
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:
72
87
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 ]
77
92
```
78
93
79
94
### ** Java**
@@ -83,17 +98,36 @@ class Solution:
83
98
``` java
84
99
class Solution {
85
100
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) {
89
123
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 ];
93
127
}
94
128
}
95
129
}
96
- return dp [target];
130
+ return f [target];
97
131
}
98
132
}
99
133
```
@@ -104,15 +138,39 @@ class Solution {
104
138
class Solution {
105
139
public:
106
140
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) {
110
166
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
+ }
113
171
}
114
172
}
115
- return dp [ target] ;
173
+ return f [target];
116
174
}
117
175
};
118
176
```
@@ -121,17 +179,72 @@ public:
121
179
122
180
``` go
123
181
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 {
127
205
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 ]
131
209
}
132
210
}
133
211
}
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 ];
135
248
}
136
249
```
137
250
0 commit comments