zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Java中的==和equals区别
    2014年06月30日
    20140625&nbsp;20:39
    20140627&nbsp;20:47
    2014年06月30日
    20140628&nbsp;16:07
    hdu 1418 抱歉 (数学)
    hdu 1302 The Snail (模拟)
    hdu 1391Number Steps
    hdu 1395 2^x mod n = 1
  • 原文地址:https://www.cnblogs.com/helman/p/11332076.html
Copyright © 2011-2022 走看看