poj 3111 (最大化平均值)

针对一个特定的问题场景——从n个珠宝中选出m个使价值和重量比最大化,本篇介绍了一种有效的算法实现方案。通过枚举价值与重量比的最大值,并利用结构体保存每个珠宝的信息,最终实现了最优解的选择。

题意:

给出n个珠宝,现在让选出m个,使得v(和)/m(和)相除得到的数字最大。
输出选择的m个珠宝。

**思路:

枚举v/m的最大值,用结构体保存珠宝的编号。输出答案既可。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 100005;
double eps = 1.0e-6;

struct Node
{
    double v,w;
    int numbers;
}a[MAXN];

struct Ans
{
    int id;
    double sub;
}ans[MAXN];

int n,k;

int cmp(Ans a,Ans b)
{
    return a.sub > b.sub;
}

int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&k);
    double x,y;
    for(int i = 0;i < n; i++) {
        scanf("%lf%lf",&x,&y);
        a[i].v = x;
        a[i].w = y;
        a[i].numbers = i+1;
    }
    double L = 0,R = 0x3f3f3f3f;
    double mid = 0;
    while(R - L > eps) {
        mid = (L+R)/2;
        for(int i = 0;i < n; i++) {
            ans[i].id = a[i].numbers;
            ans[i].sub = a[i].v-a[i].w*mid;
        }
        sort(ans,ans+n,cmp);
        double sum = 0;
        for(int i = 0;i < k; i++)
            sum += ans[i].sub;
        if(sum > 0)
            L = mid;
        else
            R = mid;
    }
    for(int i = 0;i < k; i++) {
        if(i == 0)
            printf("%d",ans[i].id);
        else
            printf(" %d",ans[i].id);
    }
    printf("\n");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值