808. 分汤
有 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 的范围内将被认为是正确的。
输入: n = 50
输出: 0.62500
解释:如果我们选择前两个操作,A 首先将变为空。
对于第三个操作,A 和 B 会同时变为空。
对于第四个操作,B 首先将变为空。
所以 A 变为空的总概率加上 A 和 B 同时变为空的概率的一半是 0.25 *(1 + 1 + 0.5 + 0)= 0.625。
输入: 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 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);}
};
下一篇:Mybatis - 核心配置解读