hdoj 4415 Assassin’s Creed 【贪心】

来源:互联网 发布:qq tim 知乎 编辑:程序博客网 时间:2024/06/04 19:05

Assassin’s Creed

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2554    Accepted Submission(s): 570


Problem Description
Ezio Auditore is a great master as an assassin. Now he has prowled in the enemies’ base successfully. He finds that the only weapon he can use is his cuff sword and the sword has durability m. There are n enemies he wants to kill and killing each enemy needs Ai durability. Every time Ezio kills an enemy he can use the enemy’s sword to kill any other Bi enemies without wasting his cuff sword’s durability. Then the enemy’s sword will break. As a master, Ezio always want to do things perfectly. He decides to kill as many enemies as he can using the minimum durability cost.
 

Input
The first line contains an integer T, the number of test cases.
For each test case:
The first line contains two integers, above mentioned n and m (1<=n<=10^5, 1<=m<=10^9).
Next n lines, each line contains two integers Ai, Bi. (0<=Ai<=10^9, 0<=Bi<=10).
 

Output
For each case, output "Case X: " (X is the case number starting from 1) followed by the number of the enemies Ezio can kill and the minimum durability cost.
 

Sample Input
23 54 15 17 72 12 24 0
 

Sample Output
Case 1: 3 4Case 2: 0 0
 


题意:你有一把耐久度m的武器。现在有n个敌人,已知杀死第i个敌人需要损耗武器a点耐久度且获得b把新武器(该武器可以杀死任意一个敌人),问你可以杀死的最大数目的敌人以及所需最低的武器损耗度。


思路:贪心。

按b值先划分两个集合,b值非0的集合记为X,b值为0的集合记为Y。统计X集合sigma(b) = sumget.

一、满足m >= min(a[i]) (i属于X),就可以杀死X集合中一个人。

这样可以想到的是只要杀死X中任意一个人就相当于杀死sumget + 1个人。那么剩下的人n - sumget - 1,贪心杀就可以了。当然要先特判sumget + 1 >= n的情况。

二、不满足,那么只能在Y集合中贪心杀了。


AC代码:


#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <set>#include <vector>#include <string>#define INF 1000000#define eps 1e-8#define MAXN (100000+10)#define MAXM (100000+10)#define Ri(a) scanf("%d", &a)#define Rl(a) scanf("%lld", &a)#define Rf(a) scanf("%lf", &a)#define Rs(a) scanf("%s", a)#define Pi(a) printf("%d\n", (a))#define Pf(a) printf("%.2lf\n", (a))#define Pl(a) printf("%lld\n", (a))#define Ps(a) printf("%s\n", (a))#define W(a) while((a)--)#define CLR(a, b) memset(a, (b), sizeof(a))#define MOD 1000000007#define LL long long#define lson o<<1, l, mid#define rson o<<1|1, mid+1, r#define ll o<<1#define rr o<<1|1#define PI acos(-1.0)#pragma comment(linker, "/STACK:102400000,102400000")#define fi first#define se secondusing namespace std;typedef pair<int, int> pii;struct Node{    int cost, get;};Node X[MAXN], Y[MAXN];bool cmp(Node a, Node b){    return a.cost < b.cost;}int numx, numy;void getY(int &ans, int &left, int &use){    for(int i = 0; i < numy; i++)    {        if(left < Y[i].cost) break;        ans++; left -= Y[i].cost; use += Y[i].cost;    }}int main(){    int t, kcase = 1; Ri(t);    W(t)    {        int n, m;        Ri(n); Ri(m); numx = 0, numy = 0;        int sumget = 0;        for(int i = 0; i < n; i++)        {            int a, b;            Ri(a), Ri(b);            if(b) {X[numx].cost = a, X[numx++].get = b; sumget += b;}            else {Y[numy].cost = a; Y[numy++].get = b;}        }        sort(X, X+numx, cmp); sort(Y, Y+numy, cmp);        int ans1 = 0, left1 = m, use1 = 0;        int ans2 = 0, left2 = m, use2 = 0;        getY(ans1, left1, use1);        if(numx && X[0].cost <= m)        {            left2 -= X[0].cost; use2 += X[0].cost; ans2++;            if(sumget >= n - 1)                ans2 = n;            else            {                int kill = n - sumget - 1;                int i = 1, j = 0;                while(kill)                {                    if(i >= numx || X[i].cost >= Y[j].cost)                    {                        if(left2 - Y[j].cost < 0) break;                        left2 -= Y[j].cost; kill--; use2 += Y[j].cost; j++;  ans2++;                    }                    else if(j >= numy || X[i].cost < Y[j].cost)                    {                        if(left2 - X[i].cost < 0) break;                        left2 -= X[i].cost; kill--; use2 += X[i].cost; i++;  ans2++;                    }                }                ans2 += sumget;            }        }        printf("Case %d: ", kcase++);        int ans, use;        if(ans1 > ans2 || (ans1 == ans2 && use1 < use2))            ans = ans1, use = use1;        else ans = ans2, use = use2;        printf("%d %d\n", ans, use);    }    return 0;}


0 0
原创粉丝点击