hdu 4415 Assassin’s Creed 贪心

http://acm.hdu.edu.cn/showproblem.php?pid=4415

题意:

Ezio 作为一个刺客他想杀掉n个人,他仅有的武器就是一把剑这把剑有攻击值m,每个人对应了两个值ai,bi,即杀掉i这个人必须消耗剑的ai的攻击之,然后你可以获得bi超级攻击法术,可以杀死bi个人。问他要怎么杀法才能是它杀的人最多而且消耗的剑的攻击之最小。

思路:

由于bi的非零的特殊性,我们将n个人按bi==0分为一组1,bi!=0分为一组2,非零的这一组只要我们能够杀掉其中的一个那么我们就可以杀掉所有的这一组的人(bi的非零性)。

对于第2组我们要么全部杀光,要么一个不杀,这样就给了我们两种情况的讨论。

如果全部杀光的话,然后我们再用得到的bi的和去杀可以用bi杀的第一组的人,然后我们还要对第二组里1-len2和第一组里0-当前杀到的值进行讨论,因为我完全可以在第二组里用m来杀他而用bi的累积和来杀第一组的,这样我们就能得到+1一个的人了。。

如果我们能够把第一组杀光然后去杀第二组,那么上边的那种情况肯定已经包括了,所以我们只能选择杀第一组,而且肯定杀不完了这是有一种情况了(本题数据很弱没有讨论这种情况)

 

View Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>

#define CL(a,num) memset((a),(num),sizeof(a))
#define iabs(x)  ((x) > 0 ? (x) : -(x))
#define Min(a , b) ((a) < (b) ? (a) : (b))
#define Max(a , b) ((a) > (b) ? (a) : (b))

#define ll __int64
#define inf 0x7f7f7f7f
#define MOD 100000007
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define test puts("<------------------->")
#define maxn 100007
#define M 100007
#define N 100007
using namespace std;
//freopen("din.txt","r",stdin);


struct node{
    int ai,bi;
}p1[N],p2[N];

int arr[N];
int n,m;

int cmp(node a,node b){
    return a.ai < b.ai;
}
int main(){
    //freopen("din.txt","r",stdin);
    int cas = 1;
    int i,t,ai,bi;
    int len1,len2;

    scanf("%d",&t);
    while (t--){

        len1 = len2 = 0;
        scanf("%d%d",&n,&m);
        int tp = m;
        for (i = 0; i < n; ++i){
            scanf("%d%d",&ai,&bi);
            if (bi == 0){
                p1[len1].ai = ai;
                p1[len1].bi = bi;
                len1++;
            }
            else{
                p2[len2].ai = ai;
                p2[len2].bi = bi;
                len2++;
            }
        }
        int ans1 = 0;
        int ans2 = 0;
        int tmp1 = 0;
        int tmp2 = 0;

        sort(p1,p1 + len1,cmp);
        sort(p2,p2 + len2,cmp);

        int tm = m;//只杀第一组
        for (i = 0; i < len1; ++i){
            if (tm >= p1[i].ai){
                ans1++;
                tmp1 += p1[i].ai;
                tm -= p1[i].ai;
            }
        }
        
        //第二组全杀
        if (len2 > 0 && m >= p2[0].ai){
            ans2 = len2;
            m -= p2[0].ai;
            tmp2 = p2[0].bi;
            for (i = 1; i < len2; ++i) tmp2 += (p2[i].bi - 1);
        }
        if (tmp2 > 0){
            for (i = len1 - 1; i >= 0 && tmp2; --i){
                tmp2--;
                ans2++;
                len1--;
            }
        }
        int len = 0;
        for (i = 0; i < len1; ++i) arr[len++] = p1[i].ai;
        for (i = 1; i < len2; ++i) arr[len++] = p2[i].ai;

        sort(arr,arr + len);

        for (i = 0; i < len; ++i){
            if (ans2 >= n) break;
            if (m >= arr[i]){
                ans2++;
                m -= arr[i];
            }
            else break;
        }
        if (ans1 > ans2 || (ans1 == ans2 && tmp1 < tmp2)){
            printf("Case %d: %d %d\n",cas++,ans1,tp - tm);
        }
        else
        printf("Case %d: %d %d\n",cas++,ans2,tp - m);
    }
    return 0;
}

 

 

posted @ 2012-09-25 17:12  E_star  阅读(312)  评论(0编辑  收藏  举报