洛谷1080国王游戏伪题解

题目传送门:https://www.luogu.org/problemnew/show/P1080

分析一下题目,那么首先我们有两个数组分别代表一个人左手和右手上的数字,就当做l[i]和r[i]好了。那么现在我们需要求的是l[0]*...l[k]/r[k+1]最大值中的最小值。我首先从末尾来看,大臣人数为n,那么最后一人他能拿到的奖赏为l[0]*...l[n-1]/r[n],那么从贪心的角度我们肯定是希望l[n]和r[n]尽量大,那么顺理成章就应该是l[n]*r[n]最大,下面给出严谨的分析过程,首先给最后一人做一个变形,奖赏为t1=l[0]*...l[n]/(l[n]*r[n]),倒数第二人奖赏为t2=l[0]*...l[n]/(l[n]*l[n-1]*r[n-1]),那么我们总是要先求出这部分的最大值的,所以最大值为max(t1,t2),此时交换两人位置,p1=l[0]*...l[n]/(l[n]*r[n]*l[n-1]),p2=l[0]*...l[n]/(l[n-1]*r[n-1]),两者中的最大值为max(p1,p2)显然t1>p1,p2>t2,那么我们现在希望最大值尽量小,所以就应该选出min(t1,p2),所以只要l[n]*r[n]>l[n-1]*r[n-1],那么我们按照l[n]*r[n]排一下序就好了。当然这位dalao说的可能更加清楚https://www.luogu.org/blog/league/solution-p1080,我和他的区别只是我一开始从后面开始推,企图避免他后面那一串问题,然而只是在我心里避免了其实并没有用

对了,之所以说这是伪题解,是因为以上整体思路只能拿到60分,懒得写高精度的选手只配及格的。

附上60分代码

#include<stdio.h>
#include<stdlib.h>
int a[10001]={0},b[10001]={0};
long long w[100001]={0};
void swap(int x,int y)
{
    int t;
    long long t1;
    t=a[x];a[x]=a[y];a[y]=t;
    t=b[x];b[x]=b[y];b[y]=t;
    t1=w[x];w[x]=w[y];w[y]=t1;
    return;
}
int quicksort(int left,int right)
{
    int i,j,mid;
    i=left;j=right;mid=w[(i+j)/2];
    while(i<=j)
    {
    while(w[i]<mid)  i++;
    while(w[j]>mid)  j--;
      if(i<=j)
      {
      swap(i,j);i++;j--;
      }
    }
    if(i<right)  quicksort(i,right);
    if(j>left)   quicksort(left,j);
    return 0;
}
int main()
{
    int i,n;
    long long sum=0,leftmul=1,max=-1;
    scanf("%d",&n);
    for(i=0;i<=n;i++)
     {
     scanf("%d%d",&a[i],&b[i]);
     w[i]=a[i]*b[i];
     }
    quicksort(1,n);
    for(i=1;i<=n;i++)
    {
      leftmul*=a[i-1];
      sum=leftmul/b[i];
      if(sum>max)  max=sum;
    }
    printf("%lld",max);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40892508/article/details/81271906