首页 > 代码库 > 洛谷P1080 国王游戏 高精度 贪心 数学推公式

洛谷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 }  

 

洛谷P1080 国王游戏 高精度 贪心 数学推公式