做法當然不能 $O(N^2)$ 枚舉吧。不過先假設 $X_1 < X_2 \cdots < X_N$ ,定義要求答案為 $f_i$ 。設 $c_i = j$ 使得 $X_i + H_i - 1 \le X_j, j > i$ ,即第 $i$ 個骨牌可以接觸到最遠哪個骨牌,如果遇上任何不能推倒的骨牌則表示為 $c_i = \infty$ 。則 $f_i$ 有如下關係﹕
\[ f_i = \begin{cases} \max_{i+1\le k\le c_i}\{f_k + k - i\} & \text{if } c_i \ne \infty \\ 1 & \text{otherwise} \end{cases}\]
首先,對於任意 $i$ ,查找 $c_i$ 的方法可以用二分搜索。至於計算 $f_i$ ,我們考慮 $c_i \ne \infty$ 的情況。經簡化可得
\[ f_i = \max_{i+1\le k\le c_i}\{f_k + k - i\} = \max_{i+1\le k\le c_i}\{f_k + k\} - i\]
設 $g_k = f_k + k$ 。即,我們從範圍 $i+1$ 至 $c_i$ 之間搜索最大的 $g_k$ 值,這就可以用線段樹輕鬆搞定了。算好 $f_i = \max_k\{g_k\} - i$ 後記得為線段樹的區間 $[i, i]$ 插入數值 $g_i = f_i + i$ 。
說來湊巧,最近與Gagguy聊天起他提起類似問題的做法,之後再做題就剛好遇上此題,所以推導公式還是比較便捷,在此先行感謝Gagguy指點。
沒有留言:
張貼留言