最大化平均值 - 二分搜索

本文介绍了一种利用二分搜索解决特定问题的方法,即在给定物品集合中选取k个物品使单位重量价值最大化。文章提供了完整的C++实现代码,并详细解释了check函数的作用及其在边界调整中的应用。

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

题意

有n个物品的重量和价值分别是xivi. 从中选出k个物品使得单位重量的价值最大.
1<=k<=n<=104, 1<=wi, vi<=106.

题解1(二分搜索)

分析

check(x): 可以选择使得单位重量的价值不小于x.

二分搜索的难点在于check函数的编写和边界的移动.

代码


#include<set>
#include<map>
#include<ctime>     //CLOCKS_PER_SEC;clock_t t=clock();
#include<cmath>     
#include<queue>
#include<bitset>
#include<cctype>
#include<cstdio>
#include<vector>
#include<string>    //getline(cin, line);
#include<sstream>   //stringstream ss(line);(ss is a stream like cin).
#include<cstdlib>
#include<cstring>
#include<float.h>   //X=FLT,DBL,LDBL;X_MANT_DIG,X_DIG,X_MIN_10_EXP,X_MIN_10_EXP,X_MIN,X_MAX,X_EPSILON
#include<limits.h>  //INT_MAX,LLONG_MAX
#include<iostream>  //ios_base::sync_with_stdio(false);
#include<algorithm>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
const double PI = acos(-1.0);
const int INF=0x3f3f3f3f;
const int Max=1;

int n, k, f[10009], w[10009];

bool check(double x){
    double y[10009];
    for(int i=0; i<n; i++)
        y[i]=f[i]-x*w[i];
    sort(y, y+n);

    double sum=0;
    for(int i=0; i<k; i++)
        sum+=y[n-i-1];
    return sum>=0;
}


int main(void){
    //freopen("in", "r", stdin); freopen("out", "w", stdout);
    while(~scanf("%d%d", &n,&k)){
        for(int i=0; i<n; i++)
            scanf("%d %d", w+i, f+i);
        double l=0, r=INF;
        for(int i=0; i<100; i++){
            double mid=(l+r)/2;
            if(check(mid)) l=mid;
            else r=mid;
        }
        printf("%.2f\n", r);
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值