Processing math: 4%

洛谷 P1570 - KC喝咖啡 - 二分答案

洛谷 P1570 - KC喝咖啡 - 二分答案

二分答案简介

二分答案是对于二分查找思想的一种应用。通过对答案出现的区间进行二分查找来判定可能的答案。二分答案一般用在以下情形的题目:

  • 直接求解答案十分复杂,或需要通过指数级别的枚举来完成。
  • 当以答案值ans作为函数自变量时,存在这样的一个单调函数可以作为区间折半的判定函数。

一般而言,使用二分答案解题通常需要以下几步:

  1. 确定答案出现的区间范围
  2. 找到单调函数(最关键步骤)
  3. 二分答案,通过单调缩小答案区间。

本题题解

依题意,需要找到最大的答案x,使得x = \frac{\sum v_i}{\sum c_i}。用搜索,复杂度为2^n,01背包也行不通,本题的x表达式不满足dp的无后效性。而题目给出 x \in [0,1000],考虑二分答案。注意本题x是小数形式,因此本题的大小判定需要针对浮点数重写比较函数或另外定义EPS。

如何二分呢?注意到x = \frac{\sum v_i}{\sum c_i},不妨设y(x) = \sum v_i - x * \sum c_i = \sum (v_i - x*c_i) 。当进行二分的时候,正在判断mid的值是否为最大的x,故需要检验 y(mid)_{max}与0的大小关系

  • y(mid)_{max} >= 0

    这说明存在这样的一组方案使得x = \frac{\sum v_i}{\sum c_i} >= mid。因此有x \in [mid,r]

  • y(mid)_{max} < 0

    这说明不存在这样的一组方案使得x = \frac{\sum v_i}{\sum c_i} >= mid,即所有的\frac{\sum v_i}{\sum c_i}都小于mid。因此有x \in [l,mid]

    另外,y(mid)_{max}很好求,只需要分别计算v_i - mid * c_i后排序去后m个即可。

答案

#include <cstdio>
#include <cmath>
#include <vector>

#define MaxN 200+5
#define EPS 1e-6
using namespace std;
int v[MaxN]; // 美味度
int c[MaxN]; // 时间

bool bigthan(double a,double b){
    return a >= b + EPS;
}

bool equal(double a,double b){
    return fabs(a-b) < EPS;
}
double bs(int n,int m){
    double l = 0,r = 1000;
    while(bigthan(r,l)){
        double mid = (r + l) / 2;
        vector<double> vec;
        for(int i = 1; i <= n; i++){
            vec.push_back(v[i] - c[i]*mid);
        }
        sort(vec.begin(),vec.end());
        double sum = 0;
        for(int i = n-1; i >= n-m; i--){
            sum += vec[i];
        }
        if(bigthan(sum,0)){
            l = mid;
        }else{
            r = mid;
        }
    }
    return r;
}
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i = 1; i <= n; i++){
        scanf("%d",&v[i]);
    }
    for(int i = 1; i <= n; i++){
        scanf("%d",&c[i]);
    }
    
    printf("%.3f",bs(n,m));
    return 0;
}
posted @   popozyl  阅读(258)  评论(0编辑  收藏  举报
编辑推荐:
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
阅读排行:
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用
点击右上角即可分享
微信分享提示