1. 程式人生 > >BZOJ 3709&&AGC 018 C——多段排序的微擾法

BZOJ 3709&&AGC 018 C——多段排序的微擾法

努力 打了 能夠 影響 等於 恢復 cost 費用流 出現

BZOJ 3709
? 有n只怪物,你的初始生命值為z。
? 為了打敗第i只怪物,你需要消耗cost[i]點生命值,但怪物死後
會使你恢復val[i]點生命值。
? 任何時候你的生命值都不能小於等於0。
? 問是否存在一種打怪順序,使得你可以打完這n只怪物而不死掉

? n≤100,000

一些怪物是賺血的,一些是虧血的。

肯定要先打完所有賺血的,再打虧血的。

打賺血的:

為了保證能夠有血,先打cos小的最保險。

微擾法證明:如果先打大一些的,如果能打,那麽打小一些的也能打,而且血更多了,一定還能打那一個大的。

所以,先打小的一定不劣。

打虧血的:

為了保證能夠有血,先打val大的最保險。

微擾法證明:為什麽會出現一個方案能打,而另一個方案就打著打著就掛了呢?

一定有:life-cos1+val1-cos2<0並且life-cos2+val2-cos1>0

(顯然,如果life-cos1<0且life-cos2>0的比較是沒有必要的。因為處於減血的階段,cos1就無論如何打不了了)

(所以只能是打了前一個,然後後一個不能打了)

即:life-cos2+val2-cos1>life-cos1+val1-cos2

那麽,就有:val2>val1

並且,打1再打2和打2再打1之後的血量一致,不影響後面的。(也是微擾法的適用條件之一)

所以,當一個怪物的val更大的時候,先打它一定不劣。

用堆維護即可。

AGC 018 C
? 有X+Y+Z個人,每個人有Ai個金幣,Bi個銀幣,Ci個銅幣。現在
選X個人提供金幣,Y個人提供銀幣,Z個人提供銅幣。
? 求最多提供多少幣。

? X+Y+Z≤100,000

話說直接跑費用流應該能過吧(雖然太暴力)

考慮如果只有金幣銀幣。

如果1提供金幣,2提供銀幣比換過來更優的話,有:A1+B2>A2+B1

A,B即金幣銀幣。

移項:A1-B1>A2-B2

所以,按照A1-B1排序,前X個提供金幣,後Y個提供銀幣。

現在加入銅幣。

之前的努力不能白費。

所以我們在按照Ai-Bi排好序的數組上進行。

留坑

BZOJ 3709&&AGC 018 C——多段排序的微擾法