POJ3111

来源:互联网 发布:网络歌曲男歌手 编辑:程序博客网 时间:2024/06/05 18:16

http://poj.org/problem?id=3111
二分+贪心
对于这个问题,我们定义C(x):=可以选择使得单位重量的价值不低于x。
因此问题就变成了sigama(vi)/sigame(wi)>=x.
变形得 sigama(vi-x*wi)>=0
因此就可以对(vi-x*wi)进行贪心的选取。
那么问题就变成了C(x)=((vi-x*wi)从大到小进行排序中的前K个和不小于0

#include<iostream>#include<cstdio>#include<queue>#include<algorithm>using namespace std;const int maxn=1e5;const int INF=1e5;int w[maxn],v[maxn],vis[maxn];int n,k;struct node{    double y;    int pos;    bool operator <(const node &n)const {        return y>n.y;    }}a[maxn];bool cmp(double x){    for(int i=0;i<n;i++){        a[i].y=v[i]-x*w[i];        a[i].pos=i;    }    sort(a,a+n);    double sum=0;    for(int i=0;i<k;i++)    {        sum+=a[i].y;        vis[i]=a[i].pos;    }    return sum>=0;}int main(){    scanf("%d%d",&n,&k);    for(int i=0;i<n;i++)        scanf("%d%d",&v[i],&w[i]);    double lb=0,ub=INF;    while(ub-lb>1e-6){        double mid=(lb+ub)/2;        if(cmp(mid)) lb=mid;        else ub=mid;    }    for(int i=0;i<k;i++)    {        printf("%d ",vis[i]+1);    }    printf("\n");    return 0;}
0 0
原创粉丝点击