NOIP 2012 提高組 DAY1 T2 國王遊戲
題目描述
恰逢 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%的數據,保證答案不超過 109;
對於 100%的數據,有 1 ≤ n ≤1,000,0 < a、b < 10000。
NOIP 2012 提高組 第一天 第二題
貪心策略 :左右手乘積最小排在前
證:x1 y1
x2 y2
... ...
-----------
xa ya
xb yb
----------
... ...
按 (xi*yi) 從小到大排序
在xa之前的乘積是一定的 我們假設為 S
xa,ya 和xb,yb交換前
xa 獲得的金幣 為(S/ya) 記為 X
xb 獲得的金幣 為((S*xa)/yb) 記為 Y
xa,ya 和xb,yb交換後
xa 獲得的金幣 為(S/yb) 記為 P
xb 獲得的金幣 為((S*xb)/ya) 記為 Q
結果是找 max(X,Y) 和max(P,Q)之中小的那個數
兩個max同乘yayb之後
X 為(S*yb) Y為 (S*xa*ya)
P 為(S*ya) Q為 (S*xb*yb)
由於要讓最大值盡量小 那麽
如果yb大於xa*ya 那麽結果取S*yb
而 xb*yb一定大於xa*ya
所以我們可以得出 xi*yi 最小時策略最優
1 /* 2 一道貪心+高精 3 貪心策略簡單 就是找左右手乘積最小的排在前邊 4 高精惡心 我不想再見這道題第二次 5 */ 6 #include<cstdio> 7 #include<cstring> 8 #include<iostream> 9 #include<algorithm> 10 #define MAXN 5010 11 #define LL long long 12 13 using namespace std; 14 15 struct node { 16 int a,b; 17 LL sum; 18 }; 19 node e[MAXN]; 20 21 int ans[MAXN],ans1[MAXN],b[MAXN]; 22 23 int n,p; 24 25 char s[MAXN]; 26 27 inline void read(int &x) { 28 int f=1;x=0;char c=getchar(); 29 while(c>‘9‘||c<‘0‘) {if(c==‘-‘) f=-1;c=getchar();} 30 while(c>=‘0‘&&c<=‘9‘) {x=(x<<1)+(x<<3)+c-48;c=getchar();} 31 x=x*f; 32 } 33 34 inline bool cmp(const node x,const node y) { 35 return x.sum<y.sum; 36 } 37 38 inline void chu(int x) { 39 b[0]=0; 40 memset(b,0,sizeof b); 41 LL k=0; 42 for(int i=ans1[0];i>=1;i--) { 43 k=k*10+ans1[i]; 44 if(k>=x) { 45 if(b[0]==0) b[0]=i; 46 b[i]=k/x; 47 k%=x; 48 } 49 } 50 } 51 52 inline void compare() { 53 if(b[0]>ans[0]) { 54 for(int i=0;i<=MAXN;i++) ans[i]=b[i]; 55 return; 56 } 57 else if(b[0]==ans[0]) { 58 for(int i=ans[0];i>=1;i--) { 59 if(b[i]>ans[i]) { 60 for(int j=0;j<=MAXN;j++) ans[j]=b[j]; 61 return; 62 } 63 } 64 } 65 } 66 67 inline void mul(int x) { 68 LL k=0; 69 memset(b,0,sizeof b); 70 for(int i=1;i<=ans1[0];i++) { 71 b[i]+=ans1[i]*x+k; 72 b[i+1]+=b[i]/10; 73 b[i]=b[i]%10; 74 } 75 for(b[0]=ans1[0];b[b[0]+1];) { 76 b[++b[0]+1]+=b[b[0]]/10; 77 b[b[0]]=b[b[0]]%10; 78 } 79 for(int i=0;i<MAXN;i++) ans1[i]=b[i]; 80 } 81 82 int main() { 83 read(n); 84 scanf("%s",s+1); 85 for(int i=strlen(s+1);i>=1;i--) ans1[++ans1[0]]=s[i]-‘0‘; 86 read(p); 87 for(int i=1;i<=n;i++) { 88 read(e[i].a); 89 read(e[i].b); 90 e[i].sum=e[i].a*e[i].b; 91 } 92 sort(e+1,e+1+n,cmp); 93 for(int i=1;i<=n;i++) { 94 chu(e[i].b); 95 compare(); 96 mul(e[i].a); 97 } 98 for(int i=ans[0];i>=1;i--) printf("%d",ans[i]); 99 printf("\n"); 100 return 0; 101 }代碼
NOIP 2012 提高組 DAY1 T2 國王遊戲