1. 程式人生 > >NOIP2018準備——貪心總結

NOIP2018準備——貪心總結

一、排序類最優決策問題 NOIP2012提高組Day2T2 恰逢 H 國國慶,國王邀請 n 位大臣來玩一個有獎遊戲。首先,他讓每個大臣在左、右 手上面分別寫下一個整數,國王自己也在左、右手上各寫一個整數。然後,讓這 n 位大臣排 成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每 位大臣獲得的金幣數分別是:排在該大臣前面的所有人的左手上的數的乘積除以他自己右 手上的數,然後向下取整得到的結果。 國王不希望某一個大臣獲得特別多的獎賞,所以他想請你幫他重新安排一下隊伍的順序, 使得獲得獎賞最多的大臣,所獲獎賞儘可能的少。注意,國王的位置始終在隊伍的最前面。 原始的想法:按b為第一關鍵字,a為第二關鍵字升序排序,這樣可以使乘積大的儘量除以大的,看似最優解的樣子,其實不然,因為若交換其中兩個,優肯更優。 對於這類排序求最值的問題,關鍵是找到最優的順序,如果直接想好像很多想法都有道理卻是錯的,所以應嚴格證明。考慮最優解的性質,即沒有辦法交換兩個數,使答案更優。那麼就開始列式子了:對於(a1,b1)在(a2,b2)前面,a1前的總乘積為s1,a1到a2的總乘積s2,為故交換前最大值為max{s1/b1,s1a1

s2/b2},交換後為max{s1/b2,s1a2s2/b1},由於s1/b2<=s1a1s2/b2,s1a2s2/b1>=s1/b1,故要使s1a2s2/b1>=s1a1s2/b2,即a1b1<a2b2,因此要以a*b升序排序。

二、選擇(匹配)類最優決策問題:

1.ssoj3909: 跳傘求生 小Q最近沉迷於《跳傘求生》遊戲。他組建了一支由n名玩家(包括他自己)組成的戰隊,編號依次為1到n。這個遊戲中,每局遊戲開始時,所有玩家都會從飛機上跳傘,選擇一個目的地降落,跳傘和降落的時間有早有晚。在某局遊戲降落前,他們在空中觀察發現地面上一共有m間房子,編號依次為1到m。其中每間房子恰好有一名敵人早於他們到達。小Q戰隊的第i名玩家擁有a_i發子彈,地面上第i間房子裡的敵人擁有b_i發子彈,消滅他可以獲得c_i點積分。每名玩家必須且只能選擇一間房子降落,然後去消滅裡面的敵人。若第i名玩家選擇了第j間房子,如果a_i>b_j,那麼他就可以消滅該敵人,獲得a_i-b_j+c_j的團隊獎勵積分,否則他會被敵人消滅。為了防止團滅,小Q不允許多名玩家選擇同一間房子,因此如果某位玩家毫無利用價值,你可以選擇讓他退出遊戲。因為房子之間的距離過長,你可以認為每名玩家在降落之後不能再去消滅其它房間裡的敵人。作為小Q戰隊的指揮,請制定一套最優的降落方案,使得最後獲得的團隊獎勵總積分最大

2.ssoj3185: Eat(eat) Teo找到了n個商店,Teo分別從第1個走到第n個。 在每個商店中Teo可以:買入1個或0個物品A,若買入1個消耗ai; 賣出1個或0個物品A,若賣出1個獲得bi。 求Teo在最後能獲得的最大價值。

3.ssoj3999: 遊戲(game) 這個遊戲是這樣的,你有一個初始序列S ,你每次可以選擇一段任意長度的連續區間,把他們+1 再膜k,給定目標序列,你需要嘗試用盡量少的操作次數將初始序列變為目標序列。作為一名優秀的OIer,您認為這個遊戲十分naive,所以您打算擼一個遊戲指令碼來取到最優解。

這三個問題的實質是一樣的:有一些價值a與另一些價值b匹配,其中一些價值a匹配b需要一定條件,且這個條件是單調的(a<b,a在b之前等),求最大匹配價值。貪心的想,先把a按滿足條件的能力排序(值、下標等),對於每個a,取滿足條件的最大價值b,用堆維護,但這樣有且僅有一個問題:對於後面的a,可能可以選取這個a的b,使全域性更優。怎麼辦呢?要使能反悔就好了。怎麼反悔呢?就是要使這個a匹配b的價值撤銷,那麼把-a扔進堆裡,後面的a若選擇了這個-a,就說明這個b改為與後面的a匹配了,這樣就完美地解決了問題。