Greedy

核心

選最好的那個

證明它不會更差

不會輸,就是最強

AtCoder abc067_b

給長度 n 序列 A
求從 A 取 k 數,使總和最大

思考方向

考慮兩長度 a > b 選一時
必選 a 較佳

 

推廣至 n 長度 a1, a2, ..., an 選一時
必選 max(a1, ..., an) 較佳

顯然找前 k 大即可

證明:對 A 由大到小 sort 後為 B
取 B1 ~ Bk

將任何 Bi 滿足 i <= k

換成 Bj 滿足 j > k

則由於 i < j 時 Bi > Bj

故總和必下降 => 不可能再改進

無法超越 = 最佳

這就是 Greedy

Kattis shopaholic

給 n 物,每湊滿 3 件一起買時最便宜者免費
求最低價格全買

思考方向

考慮 4 數以上時,取前 3 大可免費第 3 大
第 1、2 大不可能免費,故第 3 大免費最佳

 

取完後,剩下 n-3 數為同性質問題
可依相同方式處理

大到小排序,完

取前三貴的一起買,即為最佳

證明

任取兩組 X, Y
必無法透過交換變得更好

 

設 X 那組免費的較貴
則滿足 X1, X2, X3 均 >= Y1, Y2, Y3
不論如何交換,Y3 必免費
不論如何交換,只可能是 X3 換成 Y1 或 Y2

 

只可能更爛,絕不會更好

AtCoder abc131_d

有 n 件工作
第 i 件需時 Ai 死線 Bi

 

求是否可能全部工作都在死線內完成

思考方向

考慮兩工作 i, j

先做 i => 第一件 Ai / Bi 第二件 (Ai+Aj) / Bj
先做 j => 第一件 Aj / Bj 第二件 (Ai+Aj) / Bi

 

可發現第二件的死線需要對付的時間更大
故令 Bi < Bj 時
先做 i 再做 j 的可能性更佳

證明

設 Bi < Bj 經過時間 t 時,先 i 後 j 失敗
表示 t + Ai > Bi 或 t + (Ai+Aj) > Bj
換成先 j 後 i 時
因為 Bj > Bi
故由遞移律可知 t + (Ai+Aj) > Bj > Bi 必定失敗

 

設 Bi < Bj 經過時間 t 時,先 j 後 i 成功
表示 t + Aj <= Bj 且 t + (Ai+Aj) <= Bi
換成先 i 後 j 時
t + Ai < t + (Ai+Aj) <= Bi 第一件必成功
t + (Ai+Aj) <= Bi < Bj 第二件必成功

 

故先 i 再 j 必定不會更糟 => 先 i 再 j 最佳

Kattis fromatob

給 a, b 每次可對 a 做以下 2 種操作

  • a = a + 1
  • a = a / 2(a 必須為偶數)

求最小操作次數使 a 變成 b

思考方向

考慮前進的代價

 

若 a < b 則必只選加法,除法只會拖慢
要除完後使 a = b 必會先路過 b

 

若 a > b 且 a / 2 < b 時應該先除?後除?
要前進至 a / 2 + 1 先除需要 2 步
先加再除需要 3 步
故除法一律優先

Kattis minimumscalar

給兩長度 n 的序列 A, B
求將 A, B 各自排列為 A', B'
使 A'i x B'i 的總和最小化,即

\min(\sum_{i=1}^{n}A'_i\times B'_i)

思考方向

設 Ai < Aj 時 Ai x Bi 一組,Aj x Bj 一組
 

由於大乘大 + 小乘小 > 大乘小 + 大乘小
所以若 Bi < Bj 則 Bi, Bj 交換會更好

 

證明
設 a < b, c < d

a*c + b*d > a*d + b*c
=> a(c-d) > b(c-d)

=> a(d-c) < b(d-c)

=> a < b

=> OK

思考方向

對 A 先排序
則 i < j 時 Ai < Aj

 

若 Bi < Bj 則交換 Bi, Bj 更好
故最佳情況 = 無法再交換
此時滿足若 i < j 則 Bi > Bj

 

故對 A 小到大排序,對 B 大到小排序
即為所求

CSES 1632

給 n 部電影起點 Si 終點 Ei
求最少需要多少人
才能完整看完每部電影

思考方向(一)

考慮若按起始時間 S 遞增排序
則對於 Si,所有的 Ek < Si 皆可選
之後的 j > i 時 Sj >= Si > Ek 所以後續相同

 

題目轉換為給定 Si
對所有人的結束時間 E 求是否存在 < Si 者
若有,則選一改為 Ei
若沒有,則需要新增 1 個人以 Ei 結束

 

若不存在,表示所有 Ek >= Si
可由 min(E) >= Si 判定
故需 priority_queue

思考方向(二)

按 E 遞增排序
則對於 i 尋找 Ek < Si 可接續
不存在時,人數 +1

 

但由於 Si 沒有單調遞增
故存在候補 Ex < Ey < Si 時
由於 Ex 可能性完整覆蓋 Ey
故優先選較差的 Ey 會更好

 

由上可推得取最大 Ek 使得 Ek < Si 最佳
故需可 lower_bound 的資結
需要 set/map

Kattis vegetables

給 n 件東西的重量,以及比例 r
每次可選一件東西切一刀變 2 件
這 2 件重量和 = 原本東西
但兩邊重可自由調配

 

求使最小重量 > 最大重量 * r

思考方向

瓶頸出在最大值,且操作只能減少
切分時一大一小,不如均等

 

考慮把最大值切分,直到滿足條件為止

思考方向

考慮 1000, 320 且 r = 0.9 時
切成 500, 500, 320(一刀)
再切成 320, 250, 250, 250, 250(三刀)

 

不如切成 333, 333, 333, 320(兩刀)
可記錄為
1000/1, 320/1

=> 1000/2, 320/1

=> 1000/3, 320/1

 

既然適合均等,就記錄刀數使刀數 + 1
不真的切分

歡樂練習時間

Greedy

By sa072686

Greedy

  • 209