Problem#

題目說有 n 個杯子,從最上面的那個杯子開始倒水,總共倒 p 杯水,每個杯子只要到一杯就滿,往滿的水杯中倒水會往兩側溢出 1/2 的水,
給你倒水的總杯數 p 問你第 r 列第 c 個的水杯的狀態。
0 <= p <= 1090 <= r <= c < 100
想法#
從最上面那杯開始倒水,可以一次倒全部的水,假如一杯水杯超過 1.0,就往兩側倒 (b[i]-1)/2 的水
可以用一個二維陣列維護 dp[r][c] 的水量,一杯水(dp[i][j])中的水來自其左上(dp[i-1][j-1])和右上(dp[i-1][j])的水漏下來
接著就模擬一次流水即可。
- 時間複雜度: $\mathcal{O}(N^2)$
- 只要掃一遍所有的水杯就倒完了
- 空間複雜度: $\mathcal{O}(N^2)$
AC Code#
賞析#
-
另一個 bottom up 作法 跟我不一樣的是,它是從第
i杯往下流i+1;我的方法是看第i杯從i-1流 -
壓縮成 1D array 的作法 Credit
壓縮成 1D array 的作法 1
2
3
4
5
6
7
8double champagneTower(int p, int r, int c) {
double dp[101] = {0.0};
dp[0] = p;
for(int row = 1; row <= r; row++)
for(int i = row; i >= 0; i--)
dp[i+1] += dp[i] = max(0.0, (dp[i]-1)/2);
return min(dp[c], 1.0);
}
心得#
一開始想複雜了,一直想著要一杯一杯模擬,看了題解才突破盲點,可以一次倒完全部