【最大化平均值】POJ3111-K Best

【题目大意】

给出v[]和w[],求【最大化平均值】POJ3111-K Best的最大值。

【思路】

二分s(S)的值,可变形为s(S)*Σw>=Σv,所以只需要把求出x*w[i]-v[i],看看前k个的和是否大于等于0,大于等于0就满足条件。

由于进度非常高,注意二分的写法。

*原本在check(mid)=1之后会存下ansqueue,然后再输出,就wa了。 然而改成直接输出最后一次check的序列(不管返回是0还是1)。不明白为什么。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=+;
const double eps=1.0e-6;
int n,k,v[MAXN],w[MAXN];
int ansqueue[MAXN];
struct node
{
double rem;
int id;
bool operator < (const node &x) const
{
return (rem>x.rem);
}
};
node queue[MAXN]; int check(double x)
{
for (int i=;i<=n;i++)
{
queue[i].rem=v[i]-x*w[i];
queue[i].id=i;
}
sort(queue+,queue+n+);
double sum=;
for (int i=;i<=k;i++) sum+=queue[i].rem;
if (sum>=0.0) return ;
else return ;
} void solve()
{
for (int i=;i<=n;i++) scanf("%d%d",&v[i],&w[i]);
double lb=0.0,ub=0x3f3f3f3f;
while (ub-lb>eps)
{
double mid=(lb+ub)/;
if (check(mid)) lb=mid;
else ub=mid;
}
for (int i=;i<=k;i++)
{
printf("%d",queue[i].id);
if (i!=k) cout<<' ';
}
/*我原本在check(mid)=1之后会存下ansqueue,然后再输出,就wa了。
然而改成直接输出最后一次check的序列(不管返回是0还是1)。不明白为什么。*/
cout<<endl;
} int main()
{
while (scanf("%d%d",&n,&k)!=EOF) solve();
return ;
}
上一篇:【BZOJ3232】圈地游戏 分数规划+最小割


下一篇:深入浅出理解QTimeLine类