0w1

CFR 416 C. Booking System ( Greedy )

Problem - 416C - Codeforces
題意:
給一堆客人的要求,用人數和獲益描述,接著給一些桌子其容量。每個桌子只能招待一組客人的要求,而某個桌子可以招待一組客人若且唯若其容量不小於人數,此時若選擇配對則獲得該獲益。求最大總獲益,並輸出對應配對。
解法:
考慮由當前最大獲益的要求開始滿足,總是將該組放到可容的最小桌子。試反證這樣是錯的,那麼代表該桌子寧願塞另一個收益更小的客人而放棄這組,顯然不合理,故貪心法正確。

int N;
vi C, P;
int K;
vi R;

void init(){
    cin >> N;
    C = P = vi( N );
    for( int i = 0; i < N; ++i )
        cin >> C[ i ] >> P[ i ];
    cin >> K;
    R = vi( K );
    for( int i = 0; i < K; ++i )
        cin >> R[ i ];
}

typedef tuple< int, int, int > tiii;
vector< tiii > request;

void preprocess(){
    for( int i = 0; i < N; ++i )
        request.emplace_back( P[ i ], C[ i ], i );
    sort( request.begin(), request.end(), greater< tiii >() );
}

void solve(){
    int profit = 0;
    vp acreq;
    vi vis( K );
    for( int i = 0; i < N; ++i ){
        int val, size, id;
        tie( val, size, id ) = request[ i ];
        int tsz = INF, tid = -1;
        for( int j = 0; j < K; ++j )
            if( not vis[ j ] and R[ j ] >= size )
                if( upmin( tsz, R[ j ] ) )
                    tid = j;
        if( tid == -1 )
            continue;
        profit += val;
        vis[ tid ] = 1;
        acreq.push_back( pii( id, tid ) );
    }
    cout << ( int ) acreq.size() << " " << profit << endl;
    for( int i = 0; i < acreq.size(); ++i )
        cout << acreq[ i ].first + 1 << " " << acreq[ i ].second + 1 << endl;
}