有两个瓶子A和B分别有N毫升水,
每次可以进行下面四种操作之一
- Serve 100 ml of soup A and 0 ml of soup B
- Serve 75 ml of soup A and 25 ml of soup B
- Serve 50 ml of soup A and 50 ml of soup B
- Serve 25 ml of soup A and 75 ml of soup B
求先倒完A的概率+0.5*(同时倒完A和B的概率)
dp[a][b]为A瓶子有a毫升 B瓶子有b毫升的要求的那个结果
那么
dp[a][b] = 0.25 * (dp[a -100][b] + dp[a -75][b - 25] +dp[a -50][b -50] + dp[a -25][b - 75])
但是题目的N <= 10^9
注意到题目的四个操作,是没有直到B瓶的操作的,那么随着N的增大,先倒完A瓶的概率越来越大,结果应该是越来越大的。
通过计算一定的值来发现当N > =N0的时候,结果和1差的很小的时候直接返回1即可,题目允许有误差。
同时为了计算方便,可以以25为一个单位,不影响最终的结果。
double[][] memory;
public double soupServings(int N) {
N = (N + 24) / 25;
if (N >= 500) return 1.0;
memory = new double[500][500];
return f(N, N);
}
double f(int a, int b) {
if (a <= 0 && b <= 0) return 0.5;
if (a <= 0) return 1.0;
if (b <= 0) return 0;
if (memory[a][b] > 0) return memory[a][b];
double res = 0;
res += f(a - 4, b);
res += f(a - 3, b - 1);
res += f(a - 2, b - 2);
res += f(a - 1, b - 3);
res *= 0.25;
memory[a][b] = res;
return res;
}