• [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
    " , ans ) ;
        }
        return 0 ;
    }
    
  • 相关阅读:
    网络分析[3] 发布NAServer到ArcGIS for Server(以Server 10.4为例)
    Vuejs环境安装与工程建立【小白Windows向】
    【C语言学习】-05 二维数组、字符串数组、多维数组
    【C语言学习】-04 一维数组、字符数组
    【C语言学习】-03 循环结构
    【C语言学习】-02 分支结构
    【C语言学习】-01 C基础
    ios layoutsubView 何时被调用
    Xcode 断点调试,取消直接进入到汇编语言界面处理
    一步一步实现iOS应用PUSH功能
  • 原文地址:https://www.cnblogs.com/hulean/p/13623510.html
Copyright © 2020-2023  润新知