P1080 國王遊戲
題目描述
恰逢 H 國國慶,國王邀請 n 位大臣來玩一個有獎遊戲。首先,他讓每個大臣在左、右手上面分別寫下一個整數,國王自己也在左、右手上各寫一個整數。然後,讓這 n 位大臣排成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若幹金幣,每位大臣獲得的金幣數分別是:排在該大臣前面的所有人的左手上的數的乘積除以他自己右手上的數,然後向下取整得到的結果。
國王不希望某一個大臣獲得特別多的獎賞,所以他想請你幫他重新安排一下隊伍的順序,使得獲得獎賞最多的大臣,所獲獎賞盡可能的少。註意,國王的位置始終在隊伍的最前面。
輸入輸出格式
輸入格式:
第一行包含一個整數 n,表示大臣的人數。
第二行包含兩個整數 a和 b,之間用一個空格隔開,分別表示國王左手和右手上的整數。
接下來 n 行,每行包含兩個整數 a 和 b,之間用一個空格隔開,分別表示每個大臣左手和右手上的整數。
輸出格式:
輸出只有一行,包含一個整數,表示重新排列後的隊伍中獲獎賞最多的大臣所獲得的金幣數。
輸入輸出樣例
輸入樣例#1:3 1 1 2 3 7 4 4 6輸出樣例#1:
2
說明
【輸入輸出樣例說明】
按 1、2、3 號大臣這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數為 2;
按 1、3、2 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數為 2;
按 2、1、3 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數為 2;
按 2、3、1 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數為 9;
按 3、1、2 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數為 2;
按 3、2、1 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數為 9。
因此,獎賞最多的大臣最少獲得 2 個金幣,答案輸出 2。
【數據範圍】
對於 20%的數據,有 1≤ n≤ 10,0 < a、b < 8;
對於 40%的數據,有 1≤ n≤20,0 < a、b < 8;
對於 60%的數據,有 1≤ n≤100;
對於 60%的數據,保證答案不超過 10^9;
對於 100%的數據,有 1 ≤ n ≤1,000,0 < a、b < 10000。
NOIP 2012 提高組 第一天 第二題
不想寫高精.jpg.
思路很簡單,就是把a*b從小到大排序
1.證明:
1)知道,如果相鄰的兩個人交換位置,只會影響到這兩個人的值,不會影響他人
2)假設相鄰的兩個人i, i + 1。設A[i] B[i] <= A[i + 1] B[i + 1],i之前所有人的左手乘積為S。
則,ans1 = max{S / B[i], S * A[i] / B[i + 1]}
若交換
則,ans2 = max{S / B[i + 1], S * A[i + 1] / B[i]}
因為,A[i] B[i] <= A[i + 1] B[i + 1]
所以,S A[i] / B[i + 1] <= S A[i + 1] / B[i]
又因為,S / B[i + 1] <= S * A[i] / B[i + 1]
所以,ans2 = S * A[i + 1] / B[i]
ans1 = max{S / B[i], S * A[i] / B[i + 1]}
所以,ans1 <= ans2
2.證明:
取 log 變成加法.
其實只與相鄰兩人的順序有關.
前後的人他們都影響不了.
推一推式子. 假設有倆人 i,j.
i 在 j 前面的答案是
max{−b i ,a i − b j }
i 在 j 後面的答案是
max{−b j ,a j − b i }
顯然 −b j < a i − b j ,−b i < a j − b i .
所以 a i − b j < a j − b i .
所以 a i + b i < a j + b j
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<queue> 7 #define lli long long int 8 using namespace std; 9 const lli MAXN=1001; 10 inline void read(lli &n) 11 { 12 char c=‘+‘;lli x=0;bool flag=0; 13 while(c<‘0‘||c>‘9‘){c=getchar();if(c==‘-‘)flag=1;} 14 while(c>=‘0‘&&c<=‘9‘){x=x*10+(c-48);c=getchar();} 15 flag==1?n=-x:n=x; 16 } 17 struct node 18 { 19 lli a,b; 20 node(){a=0;b=0;} 21 }pep[MAXN]; 22 lli comp(const node &a,const node &b) 23 { 24 return (a.a*a.b<b.a*b.b); 25 } 26 lli now=1; 27 lli ans=0; 28 int main() 29 { 30 lli n; 31 read(n); 32 read(pep[1].a);read(pep[1].b); 33 for(lli i=2;i<=n+1;i++){read(pep[i].a);read(pep[i].b);} 34 sort(pep+2,pep+n+2,comp); 35 for(lli i=1;i<=n+1;i++) 36 { 37 ans=max(ans,now/(pep[i].b)); 38 now*=pep[i].a; 39 } 40 //printf("%lld",ans); 41 cout<<ans; 42 return 0; 43 }
P1080 國王遊戲