这题真杯具,比赛的时候没做出来,虽然也是贪心的方法,但想复杂了。其实就分两种情况比较,一种是不杀带武器的人,直接把不带武器的排个序杀就是了;第二种为杀带武器的,那么带武器的是得全部杀掉的,先用耐力值杀掉消耗最小的那个带武器的人,然后数一数总的武器数,把剩下的人按消耗值排序,留下武器总数个的人,其余的用耐力值尽量杀就行了,so easy啊,真杯具。。。
/* * hdu4415/win.cpp * Created on: 2012-10-9 * Author : ben */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <queue> #include <set> #include <map> #include <stack> #include <string> #include <vector> #include <deque> #include <list> #include <functional> #include <numeric> #include <cctype> using namespace std; const int MAXN = 100005; int num, remain, sword; typedef struct { int ai; int bi; }Enemies; Enemies enemies[MAXN]; bool inline operator<(const Enemies &e1, const Enemies &e2) { return e1.ai > e2.ai; } void work1(int N, int M) { priority_queue<int> PQ; for(int i = 0; i < N; i++) { if(enemies[i].bi == 0) { PQ.push(enemies[i].ai); } } int tnum = 0; while(!PQ.empty()) { int t = PQ.top(); PQ.pop(); if(t <= M) { tnum++; M -= t; }else { break; } } if(tnum > num) { num = tnum; remain = M; }else if(tnum == num) { if(remain < M) { remain = M; } } } void work2(int N, int M) { int min = 0x7fffffff, index; for(int i = 0; i < N; i++) { if(enemies[i].bi > 0 && enemies[i].ai < min) { min = enemies[i].ai; index = i; } } if(min == 0x7fffffff) { return ; } if(M < enemies[index].ai) { return ; } M -= enemies[index].ai; int tnum = sword + 1; if(tnum >= N) { tnum = N; } priority_queue<Enemies> PQ; for(int i = 0; i < N; i++) { if(i == index) { continue; } PQ.push(enemies[i]); } while(PQ.size() > sword) { int t = PQ.top().ai; PQ.pop(); if(t <= M) { tnum++; M -= t; }else { break; } } if(tnum > num) { num = tnum; remain = M; }else if(tnum == num) { if(remain < M) { remain = M; } } } int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif int T, N, M; scanf("%d", &T); for(int t = 1; t <= T; t++) { scanf("%d%d", &N, &M); sword = 0; for(int i = 0; i < N; i++) { scanf("%d%d", &enemies[i].ai, &enemies[i].bi); sword += enemies[i].bi; } num = 0; remain = M; work1(N, M); work2(N, M); printf("Case %d: %d %d\n", t, num, M - remain); } return 0; }