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;
    }
  • 相关阅读:
    Binary Tree Inorder Traversal
    Populating Next Right Pointers in Each Node
    Minimum Depth of Binary Tree
    Majority Element
    Excel Sheet Column Number
    Reverse Bits
    Happy Number
    House Robber
    Remove Linked List Elements
    Contains Duplicate
  • 原文地址:https://www.cnblogs.com/helman/p/11332076.html
Copyright © 2011-2022 走看看