leetcode 808 概率dp及递推证明过程
作者:互联网
此题是典型的概率dp,概率dp需要从小往大走,n方次循环即可,比搜索简单很多,由于题目中均为25的倍数,我们可以将所有参数除以25。此题的递推公式是
d
p
[
i
]
[
j
]
=
0.25
∗
(
d
p
[
i
−
4
]
[
j
]
+
d
p
[
i
−
3
]
[
j
−
1
]
+
d
p
[
i
−
2
]
[
j
−
2
]
+
d
p
[
i
−
1
]
[
j
−
3
]
)
dp[i][j] = 0.25*(dp[i-4][j] + dp[i-3][j-1] + dp[i-2][j-2] + dp[i-1][j-3])
dp[i][j]=0.25∗(dp[i−4][j]+dp[i−3][j−1]+dp[i−2][j−2]+dp[i−1][j−3])
class Solution {
public:
double soupServings(int n) {
if(n > 5000)return 1;
n = ceil(n/25.0);
// dp[i][j] 表示i的A和j的B,结果需要返回的概率
double dp[n+1][n+1];
memset(dp, 0, sizeof(dp));
dp[0][0] = 0.5;
for(int i=1;i<=n;i++)dp[i][0] = 0, dp[0][i] = 1;
for(int i=1;i<=n;i++)
{
int a1 = max(0, i-4), a2 = max(0, i-3), a3 = max(0, i-2), a4 = max(0, i-1);
for(int j=1;j<=n;j++)
{
int b1 = j, b2 = max(0, j-1), b3 = max(0, j-2), b4 = max(0, j-3);
dp[i][j] = 0.25*(dp[a1][b1] + dp[a2][b2] + dp[a3][b3] + dp[a4][b4]);
}
}
return dp[n][n];
}
};
此题求的是汤A先分配完的概率+汤A和汤B同时分配完的概率 / 2。这个可以直接用递推公式推,是需要证明的。
我们用
P
(
A
)
(
i
,
j
)
P(A)(i,j)
P(A)(i,j) 表示有
i
i
i 毫升A和
j
j
j 毫升B时,A先分完的概率。
用
P
(
B
)
(
i
,
j
)
P(B)(i,j)
P(B)(i,j) 表示有
i
i
i 毫升A和
j
j
j 毫升B时,A和B同时分完的概率
P
(
A
)
P(A)
P(A) 和
P
(
B
)
P(B)
P(B) 均满足上面的递推公式,这个是可以用全概率公式推的,全概率公式一般用于拆分所有可能的情况
由于 P ( A ) P(A) P(A) 和 P ( B ) P(B) P(B) 均满足上面的递推公式,所以他们的线性组合也是一定满足的,所以此题可以直接用dp来解。
标签:概率,int,max,808,此题,递推,leetcode,dp 来源: https://blog.csdn.net/qq_39678022/article/details/120443786