POJ 2970 (优先队列)

来源:互联网 发布:openstack vsphere知乎 编辑:程序博客网 时间:2024/06/05 01:10

这里写图片描述

这里写图片描述

题意:

给出n个项目,每一个项目三个属性ai,bi,di,bi是项目完成所需要的时间,di是
时间不能超过di,如果超过可以用钱来加快速度x的金钱可以使得bi = bi - ai * x。问
最少可以花费多少时间可以使得所有项目都按时完成。

思路:

我们考虑每一个项目只要在时间限制下完成就行,但是如何操作呢?
首先:项目可以按照时间先后顺序完成,那么实际操作需要结构体排序。
其次:当遇到时间超过限制时间的时候就需要用钱了,如何使用钱?
当然是在ai最大的项目上花钱最好,所以实际操作中就用优先队列来弹出ai最大的项
目。

#include <iostream>#include <cstdio>#include <queue>#include <algorithm>using namespace std;const int maxn = 1e5+5;struct Node{    int ai,bi,di;    bool operator < (const Node &s) const       //在优先队列中按照结构体的ai从大到小排序top中ai最大    {        return s.ai > ai;    }}a[maxn];bool cmp(Node a,Node b){    return a.di < b.di;}priority_queue<Node>Q;int n;int main(){    //freopen("in.txt","r",stdin);    while(scanf("%d",&n) != EOF) {        while(!Q.empty()) Q.pop();        for(int i = 1;i <= n; i++) {            scanf("%d%d%d",&a[i].ai,&a[i].bi,&a[i].di);        }        double ans = 0;        sort(a+1,a+n+1,cmp);        long long sum = 0;        for(int i = 1;i <= n; i++) {            sum += a[i].bi;            Q.push(a[i]);            while(!Q.empty() && sum > a[i].di) {                Node temp = Q.top();                Q.pop();                if(sum - a[i].di > temp.bi) {                           sum -= temp.bi;                    ans += temp.bi*1.0/temp.ai;                }                else {                    ans += (sum-a[i].di)*1.0/temp.ai;   //根据ai 的属性可以算出所需要的钱                    temp.bi -= (sum-a[i].di);                    sum = a[i].di;                    Q.push(temp);                }            }        }        printf("%.2f\n",ans);    }    return 0;}
原创粉丝点击