洛谷P1080 国王游戏 高精度 贪心 数学推公式
洛谷P1080 国王游戏 数学推公式 高精度 贪心
然而这并不是我打出来的,抄题解。。。
将左手与右手的乘积从小到大排序,然后计算求最大值即可。(需要高精度)
证明:
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
证毕 至于高精度:
由题意知,0 < a,b < 10000,所以用10000进制的高精度进行运算就可以了
转自 新浪博客
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<ctime> 6 #include<iostream> 7 #include<algorithm> 8 using namespace std; 9 int N; 10 int a[1005],b[1005],ka,kb; 11 int ans[20000],t[20000],lena,lent,tt[20000],t2[20000],len; 12 void _qst_ab(int l,int r) 13 { 14 int i=l,j=r,ma=a[(i+j)>>1],mb=b[(i+j)>>1]; 15 while(i<=j) 16 { 17 while(a[i]*b[i]<ma*mb) i++; 18 while(a[j]*b[j]>ma*mb) j--; 19 if(i<=j) 20 { 21 swap(a[i],a[j]); 22 swap(b[i],b[j]); 23 i++;j--; 24 } 25 } 26 if(l<j) _qst_ab(l,j); 27 if(i<r) _qst_ab(i,r); 28 } 29 void _init() 30 { 31 scanf("%d%d%d",&N,&a[0],&b[0]); 32 for(int i=1;i<=N;i++) 33 scanf("%d%d",&a[i],&b[i]); 34 } 35 void _get_t(int Left,int Right) 36 { 37 for(int i=1;i<=lent;i++) 38 { 39 tt[i]+=t[i]*Left; 40 tt[i+1]+=tt[i]/10; 41 tt[i]%=10; 42 } 43 lent++; 44 while(tt[lent]>=10) 45 { 46 tt[lent+1]=tt[lent]/10; 47 tt[lent]%=10; 48 lent++; 49 } 50 while(lent>1&&tt[lent]==0) lent--; 51 len=lent; 52 memcpy(t,tt,sizeof(tt)); 53 memset(tt,0,sizeof(tt)); 54 for(int i=1,j=len;i<=len;i++,j--) 55 t2[i]=t[j]; 56 int x=0,y=0; 57 for(int i=1;i<=len;i++) 58 { 59 y=x*10+t2[i]; 60 tt[i]=y/Right; 61 x=y%Right; 62 } 63 x=1; 64 while(x<len&&tt[x]==0) x++; 65 memset(t2,0,sizeof(t2)); 66 for(int i=1,j=x;j<=len;i++,j++) 67 t2[i]=tt[j]; 68 memcpy(tt,t2,sizeof(t2)); 69 len=len+1-x; 70 } 71 bool _cmp() 72 { 73 if(len>lena) return true; 74 if(len<lena) return false; 75 for(int i=1;i<=len;i++) 76 { 77 if(ans[i]<tt[i]) return true; 78 if(ans[i]>tt[i]) return false; 79 } 80 return false; 81 } 82 void _solve() 83 { 84 _qst_ab(1,N); 85 t[1]=1;lent=1; 86 for(int i=1;i<=N;i++) 87 { 88 memset(tt,0,sizeof(tt)); 89 len=0; 90 _get_t(a[i-1],b[i]); 91 if(_cmp()) 92 { 93 memcpy(ans,tt,sizeof(tt)); 94 lena=len; 95 } 96 } 97 for(int i=1;i<=lena;i++) 98 printf("%d",ans[i]); 99 printf("\n"); 100 } 101 int main() 102 { 103 _init(); 104 _solve(); 105 return 0; 106 }