• [POJ3111]K Best


    题目大意:给你n个珠宝,每个珠宝有一个价值$v_i$和重量$w_i$,现在要选k个,使得$frac{sum v_i}{sum w_i}$最大,求这k个珠宝的编号。

    解题思路:这题和洛谷P1750的题意是一样的,变化的仅是输出的东西和数据范围。此题数据范围是$nle 100000$,所以$O(nk)$的贪心是会超时的。

    我们可以二分价值m,如果该价值可用,那么就一定有$frac{sum v_i}{sum w_i}ge m$,我们把该式变形,得$sum (v_i-w_i×m)ge 0$,于是每次以这个式子为关键字,对所有珠宝进行一次排序,然后判断前k个之和是否$ge 0$即可。时间复杂度$O(nlog ^2 n)$。

    C++ Code:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define EPS 1e-9
    int n,k;
    struct wp{
    	int v,w,id;
    	double y;
    	bool operator <(const wp& rhs)const{return y>rhs.y;}
    }a[2000001];
    bool ok(double d){
    	for(int i=1;i<=n;++i)a[i].y=a[i].v-a[i].w*d;
    	sort(a+1,a+n+1);
    	double ans=0;
    	for(int i=1;i<=k;++i)ans+=a[i].y;
    	return ans>=0;
    }
    int main(){
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;++i)
    	scanf("%d%d",&a[i].v,&a[i].w),a[i].id=i;
    	double l=0,r=1e13+1;
    	while(r-l>EPS){
    		double mid=(l+r)/2;
    		if(ok(mid))l=mid;else r=mid;
    	}
    	for(int i=1;i<=k;++i)printf("%d ",a[i].id);
    	printf("
    ");
    	return 0;
    }
    
  • 相关阅读:
    Vue路由跳转时修改页面标题
    Vue整合Quill富文本编辑器
    XML中的转义字符
    整合SSM框架环境搭建
    Android搞定权限申请
    Android实现秒开效果
    tail -f 与tail -F的区别
    druid 启动报错
    sqoop flume学习笔记
    20180911
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7353743.html
Copyright © 2020-2023  润新知