题意:
让n 位大臣排成一排,国王站在队伍的最前面。
排好队后,所有的大臣都会获得国王奖赏的若干金币,
每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
求一种排列顺序,使得得到金币最大的大臣得到的金币最少
输出最小值
先举个简单的锤子
n=2
有两种情况
左手 | 右手 | |
国王 | $a_0$ | $b_0$ |
大臣1 | $a_1$ | $b_1$ |
大臣2 | $a_2$ | $b_2$ |
可以计算得出$ans_1=max(frac{a_0}{b_1},frac{a_0*a_1}{b_2})$
左手 | 右手 | |
国王 | $a_0$ | $b_0$ |
大臣1 | $a_2$ | $b_2$ |
大臣2 | $a_1$ | $b_1$ |
可以计算得出$ans_2=max(frac{a_0}{b_2},frac{a_0*a_2}{b_1})$
对比两种情况的答案
$ans_1=max(frac{a_0}{b_1},frac{a_0*a_1}{b_2})$
$ans_2=max(frac{a_0}{b_2},frac{a_0*a_2}{b_1})$
分别设$k_1,k_2,k_3,k_4$ 对应代表上边的值
$ans_1=max(k_1,k_2)$
$ans_2=max(k_3,k_4)$
分母相同,分子大的大
因此
$k_2>k_3$
$k_4>k_1$
不妨设$ans_1<ans_2$
即$k_2<k_4$
也就是$frac{a_0*a_1}{b_2}<frac{a_0*a_2}{b_1}$
移个项,可得出
$a_1*b_1<a_2*b_2$
所以,当 $a_1*b_1<a_2*b_2$时,$ans_1<ans_2$
所以为了求出ans最小值
按l*r进行排序
注意要用高精!
#include<cstdio> #include<iostream> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define int long long #define olinr return #define _ 0 #define love_nmr 0 #define DB double struct zhi_zhang_gao_jing_qu_si { int w[5050]; int len; int &operator [] (int a) { return w[a]; } zhi_zhang_gao_jing_qu_si() { memset(w,0,sizeof w); len=1; w[1]=1; } friend zhi_zhang_gao_jing_qu_si operator * (zhi_zhang_gao_jing_qu_si &a,int b) { zhi_zhang_gao_jing_qu_si t; t.w[1]=0; t.len=a.len+10; for(int i=1;i<=t.len;i++) { t.w[i]+=a.w[i]*b; t.w[i+1]=t.w[i]/10; t.w[i]%=10; } while(t.len>1&&t.w[t.len]==0) t.len--; return t; } friend zhi_zhang_gao_jing_qu_si operator / (const zhi_zhang_gao_jing_qu_si &a,int b) { zhi_zhang_gao_jing_qu_si t; t.len=a.len; int x=0; for(int i=t.len;i>=1;i--) { t.w[i]=(x*10+a.w[i])/b; x=(x*10+a.w[i])%b; } while(t.len>1&&t.w[t.len]==0) t.len--; return t; } friend bool operator < (const zhi_zhang_gao_jing_qu_si &a,const zhi_zhang_gao_jing_qu_si &b) { if(a.len>b.len) return false; if(a.len<b.len) return true; for(int i=a.len;i>=1;i--) { if(a.w[i]<b.w[i]) return true; if(a.w[i]>b.w[i]) return false; } return true; } void out() { for(int i=len;i>=1;i--) putchar(w[i]+'0'); } }; struct node { int l,r; friend bool operator < (const node &a,const node &b) { return a.l*a.r<b.l*b.r; } }p[1050]; int n; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } signed main() { n=read(); n++; for(int i=1;i<=n;i++) { p[i].l=read(); p[i].r=read(); } sort(p+2,p+n+1); zhi_zhang_gao_jing_qu_si sm; zhi_zhang_gao_jing_qu_si ans; for(int i=1;i<=n-1;i++) { sm=sm*p[i].l; ans=max(ans,sm/p[i+1].r); } ans.out(); olinr ~~(0^_^0)+love_nmr; }