P1080 國王遊戲

2022-08-13 00:03:20 字數 1680 閱讀 9571

這道題人云亦云說是貪心。但是重點是如何證明貪心是對的。

需要給定一定的排列來使拿到最多錢的大臣拿的最少,其實就是個排序。

我們討論兩個前後關係的大臣,如何才能使答案最小。

設兩位大臣一位叫\(a\),一位叫\(b\),把他們前面的人(包括國王)的左手的乘積統稱為\(tot\)。

當\(a\)排在\(b\)前面,則\(a\)得到的錢是\(\frac\),\(b\)得到的錢是\(\frac\)。

而當\(b\)排在\(a\)前面,則\(b\)得到的錢是\(\frac\),\(a\)得到的錢是\(\frac\)。

顯然,第一種情況\(b\)拿到的錢比第二種情況\(a\)拿的錢多,並且第二種情況\(b\)拿到的錢比第一種情況\(a\)拿到的錢多。

所以這兩對大小關係我們根本不需要去比較。。。

現在設第二種情況更優。

那麼一定會有\(\frac < \frac\),可以約掉\(tot\),再同乘以\(r_ar_b\),就可以得到

\[l_b \times r_b < l_a \times r_a

\]所以在兩者之間,左手乘右手的積較小的,答案會更小。

這樣的證明可以在氣泡排序中成立,那麼其他排序呢?

也成立!難道冒泡成立的,快排就不成立啦?!

所以這就是這道題的解法:按照左手乘以右手的積從小到大排序,每個人算下自己拿的錢,取max即可。

然後要命的來了:這道題需要高精度!

不過也是簡單的高精度。因為這道題只需要處理高精乘低精和高精除以低精這兩種操作,過載運算子即可搞定。

因為我之前根本沒掌握過這些高精低精互相運算的東西,所以也抄了別人的題解。。。

**:

#include#include#includeconst int maxn = 1005;

struct nodes

} s[maxn];

int n;

int l, r;

struct int

void init(int x)}}

bool operator < (const int &rhs) const

return false;

}int operator * (const int &rhs) const

llen = i;

}if(ret.a[llen] == 0) ret.len = llen;

else ret.len = llen + 1;

return ret;

}int operator / (const int &x) const

while(ret.len > 1 && ret.a[ret.len - 1] == 0) ret.len--;

return ret;

}void print()

};int main()

return 0;

*/scanf("%d%d%d", &n, &l, &r);

for(int i = 1; i <= n; i++) scanf("%d%d", &s[i].l, &s[i].r);

std::sort(s + 1, s + n + 1);

int temp; temp.init(l);

int ans;

for(int i = 1; i <= n; i++)

ans.print();

return 0;

}

P1080 國王遊戲

題目描述 恰逢 h h國國慶,國王邀請 nn 位大臣來玩乙個有獎遊戲。首先,他讓每個大臣在左 右手上面分別寫下乙個整數,國王自己也在左 右手上各寫乙個整數。然後,讓這 nn 位大臣排成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每位大臣獲得的金幣數分別是 排在該大臣前...

P1080 國王遊戲

恰逢 hh h國國慶,國王邀請n nn 位大臣來玩乙個有獎遊戲。首先,他讓每個大臣在左 右手上面分別寫下乙個整數,國王自己也在左 右手上各寫乙個整數。然後,讓這 nnn 位大臣排成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每位大臣獲得的金幣數分別是 排在該大臣前面的...

P1080 國王遊戲

恰逢 h 國國慶,國王邀請 n 位大臣來玩乙個有獎遊戲。首先,他讓每個大臣在左 右手上面分別寫下乙個整數,國王自己也在左 右手上各寫乙個整數。然後,讓這 n 位大臣排成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每位大臣獲得的金幣數分別是 排在該大臣前面的所有人的左手...