题目来源:http://poj.org/problem?id=3111
WA到怀疑人生系列的二分。。。
思路来自POJ-Disscuss的:http://poj.org/showmessage?message_id=354940
一定要注意跳出循环时保存的是可行解。eps的精度不要太高,可能会TLE。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <cmath>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
#define ll long long
const int maxn=1e5+10;
double v[maxn],w[maxn],y[maxn];
const double eps=1e-7;
int n,k,p[maxn];
const int cmp(const int i,const int j){return y[i]<y[j];}
bool C(double x)
{
for(int i=1;i<=n;++i)
{
y[i]=v[i]-x*w[i];
p[i]=i;
}
sort(p+1,p+1+n,cmp);
double sum=0;
for(int i=n;i>=n-k+1;--i)
sum+=y[p[i]];
return sum>=0;
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
double l=0.0,r=0.0;
for(int i=1;i<=n;++i)
{
scanf("%lf%lf",&v[i],&w[i]);
r=max(r,1.0*v[i]/w[i]);
}
while(1)
{
double mid=(l+r)/2.0;
if(C(mid))
{
l=mid;
if(r-l<eps)break;
}
else r=mid;
}
sort(p+n-k+1,p+n+1);
for(int i=n-k+1;i<=n;++i)
printf("%d ",p[i]);
printf("\n");
}
return 0;
}