1. 程式人生 > 實用技巧 >sam-Toy Cars

sam-Toy Cars

sam-Toy Cars( 貪心\(\star\star \))

  • 時限:\(1s\) 記憶體:\(256M\)

Descrption

  • \(Jasio\) 是一個三歲的小男孩,他最喜歡玩玩具了,他有 \(n\) 個不同的玩具,它們都被放在了很高的架子上,所以\(Jasio\) 拿不到它們。為了讓他的房間有足夠的空間,在任何時刻地板上都不會有超過 \(k\) 個玩具(\(Jasio\) 在地板上玩玩具)。
  • \(Jasio\) 的媽媽則在房間裡陪他的兒子。當 \(Jasio\) 想玩地板上的其他玩具時,他會自己去拿。如果他想玩的玩具在架子上,他的媽媽則會幫他去拿。當她拿玩具的時候,順便也會將一個地板上的玩具放上架子使得地板上有足夠的空間。他的媽媽很清楚自己的孩子,所以他能夠預料到 \(Jasio\)
    想玩些什麼玩具。所以她想盡量的使自己去架子上拿玩具的次數儘量的少,應該怎麼安排放玩具的順序呢?

Input

  • 第一行三個整數:\(n, k, p (1 <= k <= n <= 10^5, 1 <= p <= 5\times 10^5)\),分別表示玩具的總數、地板上玩具的最多個數以及 \(Jasio\) 他想玩玩具的序列的個數。
  • 接下來 \(p\) 行每行描述一個玩具編號,表示 \(Jasio\) 想玩的玩具。

Output

  • 一個數表示 \(Jasio\) 的媽媽最少要拿多少次玩具。

Sample Input

3 2 7
1
2
3
1
3
1
2

Sample Output

4

Hint

  • \(30\%\) 的資料滿足 \(1<=n<=500,1<=k<=200,1<=p<=2000\)
  • \(50\%\) 的資料滿足 \(1<=n<=5000,1<=k<=2000,1<=p<=40000\)
  • \(100\%\) 的資料滿足 \(1 <= k <= n <= 100,000, 1 <= p <= 500,000\)
  • 來源:\(luoguSP688\)

分析

  • 最近做的貪心也比較多了,此題的貪心也不難想,顯然地上沒有就拿一個,如果地上空間還夠直接拿就行,如果地上的玩具已經有 \(k\) 個了就需要把地上的一個玩具放到架子上去,麻煩的就是究竟這 \(k\)
    件玩具應該放哪一件?
  • 究竟選擇哪件放到架子取決於,當前物品下次使用時間,如果下次使用的時間最晚,顯然就應該先把他放上去,所以我們需要維護每個時刻當前物品下次使用的時刻,我們以用類似鄰接表的方式,倒序對這 \(m\) 次的玩具使用情況進行維護,\(nxt[i]\) 表示第 \(i\) 次玩的玩具 \(a[i]\) 下一次玩的時間。
  • 實現步驟:
    1. 倒序預處理出 \(nxt[i]\)
    2. \(1\sim m\) 遍歷玩具使用情況,用一個大根堆維護當前玩具下一使用時間
      • 當前玩具如果地上有,直接下一個。
      • 當前玩具地上沒有就要從架子上取一個,但在取之前要判斷下,地上不同玩具個數是否已經有了 \(k\) 個,如果已滿,就把大根堆裡的堆頂的物品放回去。