poj3111 K Best

本文探讨了一个在大规模数据集上寻找最优解的问题,通过改进排序和二分搜索算法,实现了从时间复杂度上的显著提升。文章还提到了牛顿迭代法作为一种替代解决方案,进一步展示了算法优化在实际应用中的重要性和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:求n个东西里取k个,使它们平均值最大,输出这个k个东西序号。
思路:这题数据很大,开始我没注意二分的细节,一直TLE,顿时感觉这题有毒。

改了两个地方就AC,一个是 把排序的定义方式cmp写成结构体里对<的重载
bool cmp(node a,node b)
{
return a.b>=b.b;
}
改成:
struct node
{
double b;int t;
bool operator<(const struct node&a)const//重载运算符
{
return b>a.b;
}
}a[100000+10];

还有吧二分退出的条件改成精度控制1e-6,开始我写的都是for(int i=0;i<100;i++){}
for(int i=0;i<100;i++){
double mid=(l+r)*0.5;
if(check(mid)) l=mid;
else r=mid;
}
改成:
while(r-l>=1e-6){
double mid=(l+r)*0.5;
if(check(mid)) l=mid;
else r=mid;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int ans[100000+10],v[100000+10],w[100000+10],n,k;
struct node
{
    double b;int t;
    bool operator<(const struct node&a)const//重载运算符
    {
        return b>a.b;
    }
}a[100000+10];

bool check(double x)
{
    for(int i=1;i<=n;i++) a[i].b=v[i]-x*w[i],a[i].t=i;
    sort(a+1,a+1+n);
    double sum=0;
    for(int i=1;i<=k;i++) sum+=a[i].b,ans[i]=a[i].t;
    return sum>=0;
}

int main()
{
    while(~scanf("%d%d",&n,&k)){
        for(int i=1;i<=n;i++) scanf("%d%d",&v[i],&w[i]);
        double l=0,r=100001;
        while(r-l>=1e-6){
           double mid=(l+r)*0.5;
           if(check(mid)) l=mid;
           else r=mid;
        }
        int ok=1;
        for(int i=1;i<=k;i++){
            if(ok) ok=0;
            else printf(" ");
            printf("%d",ans[i]);
        }
        printf("\n");
    }
}

后来看讨论,这题还可以用一个数学知识:牛顿迭代解决。
以下转自 大牛的博客:

牛顿迭代:
http://blog.youkuaiyun.com/yew1eb/article/details/38728357

牛顿迭代解法:
http://blog.youkuaiyun.com/yew1eb/article/details/38730447

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值