题目:
有 A 和 B 两种类型 的汤。一开始每种类型的汤有 n 毫升。有四种分配操作:
提供 100ml 的 汤A 和 0ml 的 汤B 。
提供 75ml 的 汤A 和 25ml 的 汤B 。
提供 50ml 的 汤A 和 50ml 的 汤B 。
提供 25ml 的 汤A 和 75ml 的 汤B 。
当我们把汤分配给某人之后,汤就没有了。每个回合,我们将从四种概率同为 0.25 的操作中进行分配选择。如果汤的剩余量不足以完成某次操作,我们将尽可能分配。当两种类型的汤都分配完时,停止操作。
注意 不存在先分配 100 ml 汤B 的操作。
需要返回的值: 汤A 先分配完的概率 + 汤A和汤B 同时分配完的概率 / 2。返回值在正确答案 10-5 的范围内将被认为是正确的。
示例 1:
输入: n = 50
输出: 0.62500
解释:如果我们选择前两个操作,A 首先将变为空。
对于第三个操作,A 和 B 会同时变为空。
对于第四个操作,B 首先将变为空。
所以 A 变为空的总概率加上 A 和 B 同时变为空的概率的一半是 0.25 *(1 + 1 + 0.5 + 0)= 0.625。
示例 2:
输入: n = 100
输出: 0.71875
提示:
0 <= n <= 109
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/soup-servings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
首先,我们可以发现,这些都是25的倍数,所以所有的都除25即可,如果出现26,那么就进1,所以在进行除25的时候,先加24再除,可以解决进1的问题。
其次,我们发现会出现4中情况,第一种就是AB都没了,这种最后返回为0.5,第二种是A没了,这种为1,第三种是B没了,这种为0,第四种是AB都还有,这种直接返回剩余量即可。
最后,我们进行递归,返回最后答案即可,但是千万注意,这道题用记忆化搜索的时候,会越界,我们发现当数目特别大的时候,最后返回值会无限趋近于1,所以精剪一下,控制为4800即可(这里4800是根据经验所得,多试一试)。
代码:
-
class
Solution {
-
public:
-
double soupServings(int n) {
-
double f[
200][
200] = {
0.0};
-
function<
double(
int,
int)> dfs = [&](
int i,
int j) ->
double
-
{
-
if(i <=
0 && j <=
0)
-
return
0.5;
-
if(i <=
0)
-
return
1;
-
if(j <=
0)
-
return
0;
-
if(f[i][j] >
0)
-
return f[i][j];
-
double ans =
0.25 * (
dfs(i
-4,j) +
dfs(i
-3,j
-1) +
dfs(i
-2,j
-2) +
dfs(i
-1,j
-3));
-
f[i][j] = ans;
-
return ans;
-
};
-
return n >
4800 ?
1 :
dfs((n +
24) /
25 , (n +
24) /
25);
-
}
-
};
转载:https://blog.csdn.net/DK_Sorhic/article/details/127959018