【貪心】【P5521】[yLOI2019] 梅深不見冬

B [yLOI2019] 梅深不見冬

Background

風,吹起梅嶺的深冬;霜,如驚濤一樣洶涌;雪,飄落後把所有燒成空,

像這場,捕捉不到的夢。

醒來時已是多年之久,宮門銅環才長了鐵鏽,

也開始生出離愁。

——銀臨《梅深不見冬》

Description

給定一棵 \(n\) 個節點的樹,在樹上行走,每次要麼選擇一個沒有到達過的子節點,要麼返回父節點。想要在一個節點 \(u\) 放上梅花當且僅當 \(u\) 的任意子節點 \(v\) 都被放上了 \(w_v\) 朵梅花。在任意時刻可以收回任意節點的梅花。對於每個節點,求如果想在這個節點放梅花,則至少需要準備多少梅花。

Limitations

qwq

特殊性質1:每個節點的孩子結點個數不超過 \(2\)

特殊性質2:每個節點的孩子節點個數不超過 \(5\)

特殊性質3:任意一個節點到根的路徑上的點數不超過 \(3\),也即樹高不超過 \(3\)

對於 \(100\%\) 的數據,保證 \(1 \leq w_i \leq 1000\)

Solution

測試點 \(1\)

只有一個節點,輸出 \(w_1\) 即可。期望得分 \(5~pts\)

測試點 \(2~\sim 5\)

爆搜一個行走的順序,然後可以 \(O(n)\) 判斷是否合法。時間複雜度 \(O(n!\times n)\),期望得分 \(20~pts\)

測試點 \(6~\sim~7\)

注意到題目所規定的走法相當於按照樹的某個dfs序走,即離開某個節點時必須遍歷完它的子樹,否則子樹中一旦有一個節點沒有被遍歷到,則永遠無法返回這個節點。

如果設在點 \(u\) 上放上 \(w_u\) 朵梅花最少需要 \(ans_u\) 朵梅花的話,考慮對於 \(u\) 的兩個孩子 \(x,~y\),如果先走 \(x\),那麼首先需要準備 \(ans_x\) 朵梅花,放上了 \(w_x\) 朵梅花,剩餘了 \(ans_x - w_x\) 朵花,再走 \(y\),需要準備 \(ans_y\) 朵花,當前有 \(ans_x - w_x\),則需要額外準備 \(\max(ans_y - ans_x + w_x, 0)\) 朵花。先走 \(y\) 的情況類似,比較一下哪種情況更優即可。

時間複雜度 \(O(n)\),期望得分 \(10~pts\)

測試點 \(8~\sim 10\)

孩子節點個數不超過 \(5\),於是爆搜一下走哪個孩子的順序,用類似子任務 \(3\) 的方法統計,然後取最優的即可。

時間複雜度 \(O(n \times x!)\),其中 \(x\) 爲最大的節點孩子個數。期望得分 \(15~pts\)

測試點 \(11~\sim 14\)

樹高不超過 \(3\),考慮第 \(3\) 層的節點,答案顯然是他們自身的權值,第二層的節點,答案是第三層的權值和。

對於第一層的根節點 \(u\),考慮放滿他的孩子的花費和在這個節點上放梅花的花費的關係:

如果放滿它的孩子花費爲 \(c\),它的孩子的權值和爲 \(W\),則會剩餘 \(rest = c - W\) 朵梅花,由於 \(W\) 是個常量,\(rest\)\(c\) 正相關。考慮當 \(w_u > rest\) 時,需要額外花費 \(w_u - rest\) 元,花費爲 \(w_u - rest + rest = w_u\) 元,當 \(w_u \leq rest\) 時,花費 \(rest\) 元。由此可以發現,當 \(rest\) 減小時,所需要的花費不會增大。又因爲 \(rest\)\(c\) 正相關,因此放滿它的孩子的花費變地,在這個節點上放梅花的花費不會增加。因此最小化放滿它孩子的花費即可得到答案。

對於一個節點 \(x\),設往這個節點上放上梅花至少需要準備 \(ans_x\) 朵梅花,而 \(x\) 的權值爲 \(w_x\),我們的問題是選擇一個最優的放梅花的序列,使得最終需要準備的梅花最小。這個問題的答案是按照 \(ans_x - w_x\) 的不升序排序即可。

考慮證明這個結論:

設有兩個節點 \(i,~j\),設 \(a_i = ans_i - w_i,~a_j = ans_j - w_j\)\(a_i > a_j\)

考慮先放 \(i\) 再放 \(j\) 需要準備的梅花朵數是 \(\max(ans_i, ans_j + w_i)\)(一式),同理先放 \(j\) 所需要準備的梅花朵數是 \(\max(ans_j, ans_i + w_j)\)(二式)。

由於 \(a_i = ans_i - w_i\),得 \(ans_i = a_i + w_i\)\(ans_j\) 同理。對一式二式分別提出 \(w\)

\[\text{一式} = \max(ans_i, ans_j + w_i) = \max(a_i + w_i, ans_j + w_i) = w_i + \max(a_i, ans_j)\]

\[\text{二式} = \max(ans_j,ans_i + w_j) = w_j + \max(a_j, ans_i) = w_j + \max(a_j, a_i + w_i) = w_j + a_i + w_i\]

考慮一式的 \(\max\) 如果取 \(a_i\),那麼 \(\text{一式} = w_i + a_i < w_i + a_i + w_j = \text{二式}\)

如果取 \(ans_j\),那麼 \(\text{一式} = w_i + w_j + a_j < w_i + w_j + w_i = \text{二式}\)

因此,一式恆小於二式,先放 \(i\) 更優。

據此做數學歸納可得,按照 \(ans - w\) 的不升序排序後的序列是最優的。

於是即可排序以後用上面的方式統計答案,時間複雜度 \(O(n \log n)\),期望得分 \(20~pts\)

測試點 \(15~\sim 20\)

發現上面的結論可以應用於這棵樹上的任何一個節點,於是每個節點都按照這樣的方法排序即可。時間複雜度 \(O(n \log n)\),期望得分 \(30 pts\)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章