目录
核心
最大化平均值类题目,一般利用的累和是否大于0来判断,然后二分。
(不能用贪心分别算,再排序)
https://vjudge.net/contest/454120#problem/C
例1---K Best
题意:
Demy有n个珠宝。每一件珠宝都有一个价值()和重量()。她决定变卖一些,留下见珠宝,留下哪些珠宝可以使最大,定义为选出的K件珠宝总和和总和的比值。(即)
思路:
(1)小数二分:
每次二分的是:
(2)check函数: 对于每个都和假设的平均值比较。如果,
。 的值越大表示这个珠宝的单位价值越大。对这个值进行排序(我从从大到小排的),则对前K的珠宝每个进行累和,如果大于等于了,则说明假设的成立,因为求最大的 ,所以缩小区间。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<limits.h>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxx=1e5+10;
int n,k;
struct node
{
int id;
double v,w;
double p;
} a[maxx];
bool cmp( node aa, node bb)
{
return aa.p>bb.p;
}
bool check(double x)
{
double sum=0;
for(int i=1;i<=n;i++)
{
a[i].p=a[i].v-a[i].w*x;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=k;i++)
{
sum+=a[i].p;
}
if(sum>=0)return true;
else return false;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&a[i].v,&a[i].w);
a[i].id=i;
}
double l=0,r=1e12,mid;
while(r-l>1e-6)
{
mid=(l+r)/2;
if(check(mid))
{
l=mid;
}
else
r=mid;
}
for(int i=1;i<=k;i++)
{
if(i!=k)
printf("%d ",a[i].id);
else
printf("%d\n",a[i].id);
}
}
例2---Dropping tests
题意:
有n场考试,对于第i场考试都会有一个总题数b[i],做对题数a[i]。你可以删除K场考试的记录,使得剩余的考试最大,。
思路:
每次二分的是:,题目保证,所以二分区间为
check函数同例1,找最大的,即,或用ans记录一下,最后再乘100即可。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<limits.h>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10;
struct node
{
int a,b;
double val;
}p[1005];
int n,k;
bool cmp(node aa,node bb)
{
return aa.val>bb.val;
}
bool check(double x)
{
double sum=0;
int a[1005];
for(int i=1;i<=n;i++)
{
p[i].val=p[i].a-p[i].b*x;
}
sort(p+1,p+1+n,cmp);
for(int i=1;i<=n-k;i++)
{
sum+=p[i].val;
}
if(sum>0)return true;
else return false;
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
if(n==0&&k==0)
{
return 0;
}
for(int i=1; i<=n; i++)
{
scanf("%d",&p[i].a);
}
for(int i=1; i<=n; i++)
{
scanf("%d",&p[i].b);
}
double l=0,r=1,mid;
double ans=0;
while(r-l>1e-8)
{
mid=(l+r)/2.0;
if(check(mid))
{
ans=mid;
l=mid;
}
else
r=mid;
}
printf("%.0f\n",ans*100);
}
}