[SPOJ417]The lazy programmer 题解(单调队列,贪心)

题意

\(N\)项任务,每项任务有一个截止时间\(d\),一个完成所需时间\(b\),和一个参数\(a\),对于每一个任务,若你给他\(x\)元钱,他将会在\(b_i-a_i*x\)完成任务,现求出每个任务都必须在规定时间完成的最小花费

思路

贪心,按\(d\)从小到大排序,如果能完成就不必花钱,不然就在这个之前的任务中选一个\(a\)最大的交钱,可以证明这是最优的

优先队列维护即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std ;
const int MAXN = 1e5 + 5 ;
int T , n ;
double ans = 0 ;
struct Node {
    int a , b ;
    int d ;
} nod[ MAXN ] ;
struct qaq {
    int ai , times ;
} ;
bool operator < ( qaq x , qaq y ) {
    return x.ai < y.ai ;
}
int t ;
inline int read () {
    int tot = 0 , f = 1 ; char c = getchar () ;
    while ( c < '0' || c > '9' ) { if ( c == '-' ) f = -1 ; c = getchar () ; }
    while ( c >= '0' && c <= '9' ) { tot = tot * 10 + c - '0' ; c = getchar () ; }
    return tot * f ;
}
inline bool cmp ( Node x , Node y ) {
    if ( x.d != y.d )
        return x.d < y.d ;
    return x.a > y.a ;
}
priority_queue < qaq > q ;
signed main () {
    T = read () ;
    while ( T -- ) {
        ans = 0 ;
        n = read () ; t = 0 ;
        while ( q.size () ) q.pop () ;
        for ( int i = 1 ; i <= n ; i ++ ) {
            nod[ i ].a = read () ; nod[ i ].b = read () ; nod[ i ].d = read () ;
        }
        sort ( nod + 1 , nod + 1 + n , cmp ) ;
        for ( int i = 1 ; i <= n ; i ++ ) {
            q.push ( ( qaq ) { nod[ i ].a , nod[ i ].b } ) ;
            // cout << t << " " << nod[ i ].b << " " << nod[ i ].d << endl ;
            if ( t + nod[ i ].b <= nod[ i ].d ) { t += nod[ i ].b ; continue ; }
            int tt = t + nod[ i ].b - nod[ i ].d ;
            while ( tt ) {
                // cout << tt << endl ;
                qaq tp = q.top () ;
                q.pop () ;
                if ( tp.times >= tt ) {
                    ans += 1.0 * ( ( double ) tt / ( double ) tp.ai ) ;
                    q.push ( ( qaq ) { tp.ai , tp.times - tt } ) ;
                    tt = 0 ;
                }
                else {
                    tt -= tp.times ;
                    ans += 1.0 * ( double ) tp.times / ( double ) tp.ai ;
                }
            }
            t = nod[ i ].d ;
            // cout << t << " " << ans << endl ;
        }
        printf ( "%.2f\n" , ans ) ;
    }
    return 0 ;
}
posted @ 2020-09-06 20:41  hulean  阅读(131)  评论(0编辑  收藏  举报