poj2970 The lazy programmer 【优先队列】

A new web-design studio, called SMART (Simply Masters of ART), employs two people. The first one is a web-designer and an executive director at the same time. The second one is a programmer. The director is so a nimble guy that the studio has already got N contracts for web site development. Each contract has a deadline di.

It is known that the programmer is lazy. Usually he does not work as fast as he could. Therefore, under normal conditions the programmer needs bi of time to perform the contract number i. Fortunately, the guy is very greedy for money. If the director pays him xi dollars extra, he needs only (bi − ai xi) of time to do his job. But this extra payment does not influent other contract. It means that each contract should be paid separately to be done faster. The programmer is so greedy that he can do his job almost instantly if the extra payment is (bi ⁄ ai) dollars for the contract number i.

The director has a difficult problem to solve. He needs to organize programmer’s job and, may be, assign extra payments for some of the contracts so that all contracts are performed in time. Obviously he wishes to minimize the sum of extra payments. Help the director!

Input

The first line of the input contains the number of contracts N (1 ≤ N ≤ 100 000, integer). Each of the next N lines describes one contract and contains integer numbers aibidi (1 ≤ aibi ≤ 10 000; 1 ≤ di ≤ 1 000 000 000) separated by spaces.

Output

The output needs to contain a single real number S in the only line of file. S is the minimum sum of money which the director needs to pay extra so that the programmer could perform all contracts in time. The number must have two digits after the decimal point.

Sample Input

2
20 50 100
10 100 50

Sample Output

5.00

 

题意:有n个合同,截止日期分别是di,有个程序员,完成每个合同的时间是bi。对于合同i,给他x元钱,相应完成时间变为bi-ai*x。求需要最少的钱数,保证该程序员按时完成所有合同。

算法:所有合同,按照截止日期排序。维护一个优先队列,存储历史上完成的合同及相应使用时间。每下一个合同时间不够用,就在历史上选择ai最大的合同,将其时间用钱来买,从而增加当前合同可以使用的时间。统计付钱总额。

代码:

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>

#define llint long long
#define LEN 100000

double ans;
int n;
int d[LEN], a[LEN], b[LEN], t[LEN];

struct pair2{
    int a,len;
    bool operator < (const pair2 &tmp) const{
        return a<tmp.a;
    }
}pairs[LEN];
std::priority_queue<pair2*> pq;

void input();
void work();
void output();

int main(){
    input();
    work();
    output();

    return 0;
}

void input(){
    scanf("%d", &n);
    for(int i=0;i<n;i++){
        scanf("%d %d %d", &a[i], &b[i], &d[i]);
        t[i]=i;
    }
}
bool compareSort(const int& i, const int& j){
    return d[i]<d[j];
}
void work(){
    int pair_i=0, cur=0;
    std::sort(t, t+n, compareSort);
    for(int i=0;i<n;i++){
        int &index = t[i];
        int remain=d[index]-cur;
        if(remain>=b[index]){
            pairs[pair_i].a = a[index];
            pairs[pair_i].len = b[index];
            pq.push(&pairs[pair_i++]);
            cur += b[index];
        }else{
            pairs[pair_i].a = a[index];
            pairs[pair_i].len = remain;

            remain = b[index]-remain;
            while(!pq.empty()){
                pair2* p = pq.top();
                if (remain <= p->len){
                    p->len -= remain;
                    ans += double(remain)/a[index];
                    if (!p->len) pq.pop();
                    remain = 0;
                    break;
                }else{
                    ans += double(p->len)/a[index];
                    pq.pop();
                    remain -= p->len;
                }
            }
            if (remain){
                ans += double(remain)/a[index];
            }

            pq.push(&pairs[pair_i++]);
            cur = d[index];
        }
    }
}
void output(){
    printf("%.2f\n", ans);
}

 

posted @ 2018-12-31 16:47  jiu~  阅读(213)  评论(0编辑  收藏  举报