洛谷普及訓練場貪心的最後一題
思想上確實是貪心但因為資料範圍的問題我80%的時間都是在寫高精(魔鬼)
本題的貪心策略的求解過程幾乎是純數學推導,但一旦把握了這個方向想推出來還是比較容易的,接下來只要耐心把排序和高精寫好就可以了
那麼來說一下推導過程:
首先是本題的無後效性:每個大臣得到的金幣數並不會影響後續大臣得到的金幣數,因為每位大臣得到的金幣數都取決於自己右手的金幣數。
確定這一點之後,不妨讓我們請出隊尾的兩名大臣葉光迪和程馳(程馳為最後),他們左右手上的數字分別是x1,y1和x2,y2。
來分類討論看看他們是如何走位排序來滿足貪心國王的企圖:
假設前面所有大臣左手數字總和為w
1.葉光迪在程馳前面時,他得到的金幣數為 w/y1 ,而程馳得到的金幣數為 w*x1/y2 。因此最多金幣數gold1即為兩式中較大的一項
2.程馳在葉光迪前面時,同理,最多金幣數gold2為 w/y2 和w*x2/y1 中較大的一項
由題意得,既然葉光迪在程馳前面,那麼說明gold1一定小於gold2,不然不會這麼排序
本題最難理解的地方來了:若gold1
為什麼呢? 進行一下數學推導:1.w*x2/y1>w/y1 w*x1/y2>w/y2
2.gold1和gold2不可能分別等於w/y1和w/y2(不符題意,自行證明)
3.當gold1=w/y1(w/y1>w*x1/y2) w/y2
這樣,我們很愉快地得出了貪心策略:將左右手乘積小的大臣排在前面
感謝葉光迪和程馳大臣
1 #include2 #include3int n,l=1,a[100010],b[100010],c[100010];4
int g[1000010];5
void cheng(int x),chu(),sort(int l,int
r);6
intmain()
714 g[1]=b[0
]; 15
for(int i=1;i)
16cheng(i); chu();
17for(int i=l;i>=1;i--) printf("%d"
,g[i]);
18return0;
19}2021
void
chu()
27while(g[l]==0) l--;
28if(l==0) printf("
1\n"
); 29}30
31void cheng(int
x)39 l++;
40while(g[l]>9)41
46if(g[l]==0) l--;47}
4849
void sort(int l,int
r)5073}
74if(l75sort(l,ri);
76if(le77sort(le,r);
78 }
P1080 國王遊戲
題目描述 恰逢 h h國國慶,國王邀請 nn 位大臣來玩乙個有獎遊戲。首先,他讓每個大臣在左 右手上面分別寫下乙個整數,國王自己也在左 右手上各寫乙個整數。然後,讓這 nn 位大臣排成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每位大臣獲得的金幣數分別是 排在該大臣前...
洛谷 1080 國王遊戲
題目描述 恰逢 h h國國慶,國王邀請 n 位大臣來玩乙個有獎遊戲。首先,他讓每個大臣在左 右手上面分別寫下乙個整數,國王自己也在左 右手上各寫乙個整數。然後,讓這 n 位大臣排成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每位大臣獲得的金幣數分別是 排在該大臣前面的...
P1080 國王遊戲
恰逢 hh h國國慶,國王邀請n nn 位大臣來玩乙個有獎遊戲。首先,他讓每個大臣在左 右手上面分別寫下乙個整數,國王自己也在左 右手上各寫乙個整數。然後,讓這 nnn 位大臣排成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每位大臣獲得的金幣數分別是 排在該大臣前面的...