• 01分数规划——POJ3111


    题目链接

    题目含义

    寻找k个钻石,使得sigmaVi/sigmaWi最大,然后输出这些钻石的序号

    题目分析

    若使sigmaVi/sigmaWi取得最大值,那么取任意k个钻石的答案ans

    ans<=sigmaVi/sigmaWi

    转换一下就是  sigmaVi-sigmaWi*ans>=0

    再转换一下就是  sigma(  Vi-Wi*ans  )>=0

    ans用二分来找,如果满足上面的式子low=mid

    否则high=mid

    至于输出序号,我用的结构体和vector存储每次二分的序号

    题目代码

    注意二分上界开大一点

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int maxn=1e5+7;
    const double eps=1e-7;
    struct Node{
        int id;
        double v,w,val;
    }node[maxn];
    bool cmp(Node a,Node b){
        return a.val>b.val;
    }
    int n,k;
    double r,l,mid,sum;
    vector<int>v;
    int main(){
        scanf("%d%d",&n,&k);
        l=0.0;r=3000;
        for(int i=1;i<=n;i++){
            scanf("%lf%lf",&node[i].v,&node[i].w);
            node[i].id=i;
            r=max(r,node[i].v/node[i].w);
        }
        while(r-l>eps){
            mid=(l+r)/2;
            for(int i=1;i<=n;i++)
                node[i].val=node[i].v-node[i].w*mid;
            sum=0;
            v.clear();
            sort(node+1,node+1+n,cmp);
            for(int i=1;i<=k;i++){
                sum+=node[i].val;
                v.push_back(node[i].id);
            }
            if(sum>=0)l=mid;
            else r=mid;
        }
    //    sort(v.begin(),v.end());
        for(int i=0;i<v.size();i++){
            if(!i)printf("%d",v[i]);
            else printf(" %d",v[i]);
        }
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    Electron应用打包、自动升级
    使用javascript处理nginx的请求
    使用Electron开发桌面应用
    VSCode、VBox搭建C/C++开发环境
    树莓派搭建Nexus2私服
    Tom猫小游戏功能实现
    如何配置webpack让浏览器自动补全前缀
    git 常用操作
    数组的一些常用操作
    ES6 的模块化
  • 原文地址:https://www.cnblogs.com/helman/p/11332076.html
Copyright © 2020-2023  润新知