hdu 4415 Assassin’s Creed 贪心

/*这道题一眼就能看出是个贪心。
但是做的时候想了N种策略最后都证明是错的。
多亏dp哥。
题意就不说了。
这道题要求在尽量多杀怪的情况下保证花费最少。
杀怪有2中方法 用怪物的剑 用自己的剑的耐久
题目说了杀一个怪 。可以获得数量不等的剑。那么首先我们用耐久杀一个能在获得剑不为零的情况下花费耐久最小的怪。
这样一来 我们肯定可以杀光那些带剑的怪。我们先假设用剑把带剑的杀光 ,把可以获得的剑的数量算出来。
把杀了第一个后剩下的怪物分2个集合 有剑的 b和 无剑的 a0
那那个集合都按花费的从小到大排序。
1.如果 b中最小的比a0最小的小。用耐久杀b中最小的。同时用原本杀b中最小的剑杀a0中最大的.
2.如果b中最小的比a0最小的大。用耐久杀a0最小的。
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 100001
using namespace std;
int a0[N];//无剑怪
int b[N];//有剑怪
int n,m,sum,x,y,i0,ib,d,tn;
int main()
{
    int T,index;
    scanf("%d",&T);
    index=0;
    while(T--)
    {
        scanf("%d%d",&n,&m);
        i0=0;ib=0;tn=0;d=0;sum=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            if(!y)
            {
                a0[i0++]=x;
            }
            else
            {
                b[ib++]=x;
                sum+=y;
            }
        }
        sort(a0,a0+i0);
        sort(b,b+ib);
        printf("Case %d: ",++index);
        if(m>=b[0]&&ib>0)
        {
            m-=b[0];
            tn+=ib;
            d+=b[0];
            if(sum-(ib-1)>=i0)
            {
                printf("%d %d\n",n,d);
                continue;
            }
            else
            {
                int ai=0,bi=1,limit;
                tn+=sum-(ib-1);
                limit=i0-(sum-(ib-1));
                while(ai<limit&&bi<ib)
                {
                    if(a0[ai]<b[bi])
                    {
                        m-=a0[ai];
                        if(m<0)
                            break;
                        d+=a0[ai];
                        ai++;
                    }
                    else
                    {
                        m-=b[bi];
                         if(m<0)
                            break;
                        d+=b[bi];
                        bi++;
                        limit--;
                    }
                     tn++;
                }
            }
        }
        else
        {
            for(int i=0;i<i0;i++)
            {
                if(m>=a0[i])
                {
                    m-=a0[i];
                    d+=a0[i];
                    tn++;
                }
                else
                    break;
            }
        }
        printf("%d %d\n",tn,d);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值