zoukankan      html  css  js  c++  java
  • 01分数规划

    01分数规划,即给定模型求sum(ai)/sum(bi)的最值;

    我们可以改变一下式子的形态:

    sum(ai)/sum(bi)>=L

    =sum(ai)-L*sum(bi)>=0

    所以我们可以通过二分判断L的取值;

    标准的二分代码:

    #include<cstdio>
    #include<algorithm>
    #include<ctype.h>
    #include<string.h>
    #include<math.h>
    
    using namespace std;
    #define ll long long
    
    inline char read() {
        static const int IN_LEN = 1000000;
        static char buf[IN_LEN], *s, *t;
        return (s==t?t=(s=buf)+fread(buf,1,IN_LEN,stdin),(s==t?-1:*s++):*s++);
    }
    template<class T>
    inline void read(T &x) {
        static bool iosig;
        static char c;
        for (iosig=false, c=read(); !isdigit(c); c=read()) {
            if (c == '-') iosig=true;
            if (c == -1) return;
        }
        for (x=0; isdigit(c); c=read()) x=((x+(x<<2))<<1)+(c^'0');
        if (iosig) x=-x;
    }
    
    const int N = 100005;
    int n, k, a[N], b[N], g[N];
    double f[N];
    inline bool cmp(int x, int y){ return f[x]>f[y];}
    inline double check(double x){
        for(int i=1; i<=n; ++i) f[i]=a[i]-b[i]*x, g[i]=i;
        nth_element(g+1, g+k+1, g+n+1, cmp);
        ll sa=0, sb=0;
        for(int i=1; i<=k; ++i) sa+=a[g[i]], sb+=b[g[i]];
        return (double)sa/sb;
    }
    int main() {
        read(n), read(k);
        for(int i=1; i<=n; ++i) read(a[i]);
        for(int i=1; i<=n; ++i) read(b[i]);
        double l=0, r=1e6, ans=0;
        while(r-l>1e-7){
            double mid=(l+r)/2;
            if(check(mid)>=mid) ans=mid, l=mid; else r=mid;
        }
        return printf("%.4f", ans), 0;
    }
  • 相关阅读:
    Nodejs chrome 调试node-inspector
    Nodejs 文件修改自动重启扩展
    PHP post & get请求
    mysql 忘记root密码
    Linux安装mysql
    Linux 安装reids
    技术 | TypeScript
    秦涛:深度学习的五个挑战和其解决方案
    人脸检测与识别的趋势和分析
    370 门免费编程与计算机科学在线课程
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11493684.html
Copyright © 2011-2022 走看看