【HDU】5859 Captain is coding【优先队列贪心】

题目链接:Captain is coding

二分Z用了多少次,Z肯定最先用,然后枚举deadline小的用了多少deadline大的,再优先队列模拟

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 1005 ;

struct Node {
    int c , d ;
    Node () {}
    Node ( int c , int d ) : c ( c ) , d ( d ) {}
    bool operator < ( const Node& a ) const {
        return c < a.c ;
    }
} ;

priority_queue < int > q , q2 ;
int n , x , y , z , w ;
Node a[MAXN] , b[MAXN] ;
int vis[MAXN] ;
int na , nb ;

int check ( int t ) {
    if ( na + nb + t <= x ) {
        int now = w + t * z , ok = 1 ;
        while ( !q.empty () ) q.pop () ;
        int k = 1 , l = 1 ;
        for ( int j = 1 ; j <= na + nb ; ++ j ) {
            while ( k <= nb && b[k].c <= now ) {
                q.push ( b[k].d ) ;
                k ++ ;
            }
            while ( l <= na && a[l].c <= now ) {
                q.push ( a[l].d ) ;
                l ++ ;
            }
            if ( q.empty () ) {
                ok = 0 ;
                break ;
            }
            now += q.top () ;
            q.pop () ;
        }
        if ( !ok ) return 0 ;
        return 1 ;
    } else {
        int tot = x - na ;
        for ( int i = max ( 0 , x - na - t ) ; i <= min ( tot , nb ) ; ++ i ) {
            int used = min ( t , tot - i ) ;
            int now = w + used * z , ok = 1 ;
            while ( !q.empty () ) q.pop () ;
            while ( !q2.empty () ) q2.pop () ;
            int k = 1 , l = 1 , cnt = 0 ;
            for ( int j = 1 ; j <= i + na ; ++ j ) {
                while ( k <= nb && b[k].c <= now ) {
                    q2.push ( b[k].d ) ;
                    k ++ ;
                }
                while ( l <= na && a[l].c <= now ) {
                    q.push ( a[l].d ) ;
                    l ++ ;
                }
                if ( !q.empty () ) {
                    now += q.top () ;
                    q.pop () ;
                } else if ( cnt < i && !q2.empty () ) {
                    now += q2.top () ;
                    q2.pop () ;
                    ++ cnt ;
                }
            }
            if ( !q.empty () || l <= na ) continue ;
            now += ( t - used ) * z ;
            for ( int j = 1 ; j <= nb - cnt ; ++ j ) {
                while ( k <= nb && b[k].c <= now ) {
                    q2.push ( b[k].d ) ;
                    k ++ ;
                }

                if ( q2.empty () ) {
                    ok = 0 ;
                    break ;
                }
                now += q2.top () ;
                q2.pop () ;
            }
            if ( ok ) {
                return 1 ;
            }
        }
        return 0 ;
    }
}

void solve ( int T ) {
    int f = 0 ;
    na = nb = 0 ;
    scanf ( "%d%d%d%d%d" , &n , &x , &y , &w , &z ) ;
    if ( x > y ) {
        swap ( x , y ) ;
        f = 1 ;
    }
    for ( int i = 1 ; i <= n ; ++ i ) {
        int c , d ;
        char be[3] ;
        scanf ( "%d%d%s" , &c , &d , be ) ;
        if ( be[0] == 'A' && !f || be[0] == 'B' && f ) a[++ na] = Node ( c , d ) ;
        else b[++ nb] = Node ( c , d ) ;
    }
    if ( x < na || y < na + nb ) {
        printf ( "Poor Captain Chen\n" ) ;
        return ;
    }
    sort ( a + 1 , a + na + 1 ) ;
    sort ( b + 1 , b + nb + 1 ) ;
    int l = 0 , r = y - na - nb , ok = 0 ;
    while ( l < r ) {
        int m = l + r >> 1 ;
        if ( check ( m ) ) {
            ok = 1 ;
            r = m ;
        } else l = m + 1 ;
    }
    if ( check ( l ) ) ok = 1 ;
    if ( !ok ) printf ( "Poor Captain Chen\n" ) ;
    else printf ( "%d\n" , l + na + nb ) ;
}

int main () {
    int T ;
    scanf ( "%d" , &T ) ;
    for ( int i = 1 ; i <= T ; ++ i ) {
        solve ( i ) ;
    }
    return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值