• 洛谷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("
    ");  
    100 }  
    101 int main()  
    102 {  
    103     _init();  
    104     _solve();  
    105     return 0;  
    106 }  
  • 相关阅读:
    js压缩图片上传插件localResizeIMG
    valueOf函数详解
    垂直居中
    word-wrap,word-break,white-space
    理解bind函数
    float失效的情况
    塞码考试系统里的输入,到底是怎么回事
    理解position:relative
    border实现三角形的原理
    函数是对象,函数名是指针
  • 原文地址:https://www.cnblogs.com/third2333/p/7071426.html
Copyright © 2020-2023  润新知