808. Soup Servings

There are two types of soup: type A and type B. Initially we have N ml of each type of soup. There are four kinds of operations:

  1. Serve 100 ml of soup A and 0 ml of soup B
  2. Serve 75 ml of soup A and 25 ml of soup B
  3. Serve 50 ml of soup A and 50 ml of soup B
  4. Serve 25 ml of soup A and 75 ml of soup B

When we serve some soup, we give it to someone and we no longer have it.  Each turn, we will choose from the four operations with equal probability 0.25. If the remaining volume of soup is not enough to complete the operation, we will serve as much as we can.  We stop once we no longer have some quantity of both types of soup.

Note that we do not have the operation where all 100 ml's of soup B are used first.  

Return the probability that soup A will be empty first, plus half the probability that A and B become empty at the same time.

 

Example:
Input: N = 50
Output: 0.625
Explanation: 
If we choose the first two operations, A will become empty first. For the third operation, A and B will become empty at the same time. For the fourth operation, B will become empty first. So the total probability of A becoming empty first plus half the probability that A and B become empty at the same time, is 0.25 * (1 + 1 + 0.5 + 0) = 0.625.

Notes:

  • 0 <= N <= 10^9
  • Answers within 10^-6 of the true value will be accepted as correct.

题目大意:

有2种soup A和B, 用来提供给客户。 共有4种操作。 提供soup的时候,如果某种已经提供完毕,则结束。如果某种不够,则尽最大可能提供该种soup。求 A先结束的概率以及 A和B同时结束的概率的一半的 和。 其中B不能先结束。

class Solution {
    //使用数组来缓存已经 计算过的结果,进而在递归中剪枝。 
    double[][] memo = new double[200][200];
    public double soupServings(int N) {
        //>5000 trick 
        //技巧,(N+24)/25 进而将25,50,75,100 缩减到 1,2,3,4. 从而减少memo 的使用。
        return N >= 5000 ?  1.0 : getProbability((N+24)/25, (N+24)/25);
    }

    //返回 A为a ml, B为bml 情况下,A先空以及AB同时为空的概率之和。
    public double getProbability(int a, int b) {
        //A 和B 同时为空的概率的 half。 这里<0 意味着不够serve。
        if (a <= 0 && b <= 0) return 0.5;
        //A 为空的概率为1
        if (a <= 0) return 1;
        //B 不可能在 A不空的情况下为空。
        if (b <= 0) return 0;
        if (memo[a][b] > 0) return memo[a][b];
        //当前阶段,分别选择 4个operation 中的某一个operation,进入下一层迭代。
        memo[a][b] = 0.25 * (getProbability(a - 4, b) + getProbability(a - 3, b - 1) + getProbability(a - 2, b - 2) + getProbability(a - 1, b - 3));
        return memo[a][b];
    }
}

参考:https://leetcode.com/problems/soup-servings/discuss/121711/C++JavaPython-When-N-greater-4800-just-return-1

你可能感兴趣的:(Leetcode,面试题)