Problem#
題目說有 n
個杯子,從最上面的那個杯子開始倒水,總共倒 p
杯水,每個杯子只要到一杯就滿,往滿的水杯中倒水會往兩側溢出 1/2
的水,
給你倒水的總杯數 p
問你第 r
列第 c
個的水杯的狀態。
0 <= p <= 109
0 <= 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);
}
心得#
一開始想複雜了,一直想著要一杯一杯模擬,看了題解才突破盲點,可以一次倒完全部