[高精度][貪心]Luogu 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。
題解
-
如果i和j兩個相鄰那麽i排在j前面的必要條件是
-
total*a[i]/b[j]<total*a[j]/b[i]
-
也就是說 a[i]*b[i]<a[j]*b[j]
-
而本題中,n<1000,a,b<10000
-
1000個10000乘起來那肯定存不下
-
所以要用高精度
代碼
1 #include<cstdio> 2 int n,l=1,a[100010],b[100010],c[100010],g[1000010]; 3 void gj1(int x) 4 { 5 for(int i=1;i<=l;i++) g[i]*=b[x]; 6 for(int i=1;i<=l;i++) 7 { 8 g[i+1]+=(g[i]/10); 9 g[i]%=10; 10 } 11 l++; 12 while(g[l]>9) 13 { 14 g[l+1]+=(g[l]/10); 15 g[l]%=10; 16 l++; 17 } 18 if(g[l]==0) l--; 19 } 20 void gj2() 21 { 22 for(int i=l;i>=1;i--) 23 { 24 g[i-1]+=((g[i]%c[n])*10); 25 g[i]/=c[n]; 26 } 27 while (g[l]==0) l--; 28 if(l==0) printf("1\n"); 29 } 30 void qsort(int l,int r) 31 { 32 int i=l,j=r,mid=a[(l+r)/2]; 33 while(i<=j) 34 { 35 while(a[i]<mid) i++; 36 while(a[j]>mid) j--; 37 if(i<=j) 38 { 39 int t=a[i]; a[i]=a[j]; a[j]=t; 40 t=b[i]; b[i]=b[j]; b[j]=t; 41 t=c[i]; c[i]=a[j]; c[j]=t; 42 i++; j--; 43 } 44 } 45 if(l<j) qsort(l,j); 46 if(i<r) qsort(i,r); 47 } 48 int main() 49 { 50 scanf("%d",&n); 51 scanf("%d %d",&b[0],&c[0]); 52 for(int i=1;i<=n;i++) 53 { 54 scanf("%d %d",&b[i],&c[i]); 55 a[i]=b[i]*c[i]; 56 } 57 qsort(1,n); 58 g[1]=b[0]; 59 for(int i=1;i<n;i++) gj1(i); 60 gj2(); 61 for(int i=l;i>=1;i--) printf("%d",g[i]); 62 return 0; 63 }
[高精度][貪心]Luogu P1080 國王遊戲