飞道的博客

入门力扣自学笔记202 C++ (题目编号:808)

284人阅读  评论(0)

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 的范围内将被认为是正确的。


示例 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是根据经验所得,多试一试)。


代码:


  
  1. class Solution {
  2. public:
  3. double soupServings(int n) {
  4. double f[ 200][ 200] = { 0.0};
  5. function< double( int, int)> dfs = [&]( int i, int j) -> double
  6. {
  7. if(i <= 0 && j <= 0)
  8. return 0.5;
  9. if(i <= 0)
  10. return 1;
  11. if(j <= 0)
  12. return 0;
  13. if(f[i][j] > 0)
  14. return f[i][j];
  15. double ans = 0.25 * ( dfs(i -4,j) + dfs(i -3,j -1) + dfs(i -2,j -2) + dfs(i -1,j -3));
  16. f[i][j] = ans;
  17. return ans;
  18. };
  19. return n > 4800 ? 1 : dfs((n + 24) / 25 , (n + 24) / 25);
  20. }
  21. };


转载:https://blog.csdn.net/DK_Sorhic/article/details/127959018
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场