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 的總和最小化,即
思考方向
設 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