题目传送门: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;
}