AtCoder 🔵 AISING2020E Camel Train
🔗 🔵 AISING2020E Camel Train
Problem Statement
題目簡述
有 隻駱駝排成一列。駱駝 若位於最前面的 個位置中,幸福值為 ;否則為 。求最大總幸福值。共有 組測試資料。
Constraints
約束條件
- (所有測試資料的 總和 )
- 所有輸入皆為整數
思路:反悔貪心
題型判斷
每隻駱駝有兩種可能的幸福值,取決於牠在排列中的位置是否滿足某個門檻。我們需要在排列中對每隻駱駝做出「選前方」或「選後方」的取捨,且不同駱駝的門檻值不同。這類「先選、後悔、動態調整最優集合」的結構,是反悔貪心的典型應用場景。
從暴力到核心觀察
最直觀的想法是枚舉所有 種排列,但 可以到 ,完全不可行。我們需要從問題結構中尋找可以簡化的性質。
對於兩隻駱駝 和 ,如果 (偏好前方)而 (偏好後方),在任意排列中,讓誰站在前面更有利?
考慮兩隻駱駝 和 。如果 (駱駝 偏好前方)而 (駱駝 偏好後方),那麼在任意排列中,若駱駝 排在駱駝 前面,將兩者交換不會使總幸福值變差。
直覺解釋:偏好前方的駱駝站在前面能拿到更大的值,偏好後方的駱駝站在後面能拿到更大的值。把偏好前方的往前挪、偏好後方的往後挪,兩者各得其所,整體只會更好。
因此,所有 的駱駝應該排在 的駱駝前面。兩組之間互不干擾,問題可以拆成兩個獨立的子問題。
當你需要確定元素的相對順序時,考慮交換相鄰兩元素,觀察目標函數的變化。如果交換後不會更差,就能推導出一個偏序關係。
問題分解
根據上述觀察,將駱駝分成獨立的兩組:
- 前方組():傾向站在前方。基礎貢獻先取 ,若成功排入前 名,則額外獲得差值 。
- 後方組():傾向站在後方。基礎貢獻先取 ,若成功排在後 名(即不在前 名),則額外獲得差值 。
兩組的計算方式完全對稱,下面以前方組為例做詳細推導。
前方組:反悔貪心的推導
對於前方組的駱駝,基礎幸福值(所有 )已經全部算入答案。現在的實質問題是:
在最多只能選 隻駱駝排入「前 名」的限制下,如何選取差值 ,使額外收益最大?
注意這裡的限制因駱駝而異——門檻值 大的容易滿足,小的競爭激烈。
將前方組駱駝按 從小到大排序。當我們處理到門檻值為 的駱駝時,最多只能有 隻駱駝被選入前方。隨著 增加,容量在逐步放寬。
這直接引出反悔貪心的策略:
- 按門檻值 從小到大處理每隻駱駝。
- 對於當前駱駝,先「貪心」地將它的差值選入(加入一個最小堆積)。
- 若選入後,已選數量超過當前的門檻值 ,則從堆積中彈出最小的差值——捨棄之前最不划算的選擇,即「反悔」。
當容量超限、必須捨棄時,最優策略是捨棄貢獻最小的那一個。最小堆積能在 時間內找出並移除最小值。
前方組必須按 遞增排序——門檻值越小限制越嚴格,必須優先處理。如果反過來按遞減排,會出現「早期選太多、後期才發現容量不夠」的情況,無法正確回退。
處理完所有駱駝後,堆積中剩餘的元素就是最終被選入前方的差值,全部加入答案。
後方組:對稱處理
後方組的邏輯與前方組完全對稱。基礎貢獻取 ,額外收益為 (注意此時 ,差值非負)。
關鍵差異在於:後方組的駱駝需要排在「後 名」。也就是說,對於門檻值為 的駱駝,最多只能有 隻後方組駱駝被選入後方。
處理方式:
- 按 遞減排序(等價於按剩餘空位 從小到大)。
- 已選數量超過 時,彈出最小差值。
核心技巧是交換論證將問題分解為兩個獨立子問題,以及反悔貪心處理帶有不同限制條件的選擇問題。關鍵在於將「每個元素有不同的門檻」透過排序轉化為「逐步放寬的容量限制」,再用堆積動態維護最優選擇集。
複雜度分析
- 時間複雜度: — 每組測試資料需要排序()以及對每隻駱駝進行一次堆積操作()。
- 空間複雜度: — 需要儲存分組後的駱駝差值,以及堆積的大小。
Code
1 | from heapq import heappush, heappushpop |








![Luogu 🟣 P3195 [HNOI2008] 玩具装箱](https://i.gdst.dev/cover/P3195.webp)
