• 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
    ", ans);
    }
  • 相关阅读:
    [POJ 2777]Count Color 线段树+二进制状态压缩
    [git] git push问题 解决 Updates were rejected because the tip of your current branch is behind 和每次输入用户名和密码
    [hdu-5795]A Simple Nim 博弈 尼姆博弈 SG函数打表找规律
    [codeforces1284E]New Year and Castle Construction 几何
    Spring事务相关接口以及实现类
    MyBatis与Spring整合
    实现一个简易RPC
    使用CAS实现一个超时锁
    阻塞队列
    Java中的Lock接口
  • 原文地址:https://www.cnblogs.com/jiu0821/p/10202425.html
Copyright © 2020-2023  润新知