hdu-4415-贪心

这个贪心有点炸。。


首先能发现,只要能杀一个Bi非零的,则可以根据红利至少杀死所有的Bi非零的

如果不能杀死bi非零的,那么就按ai排序从小到大杀。


如果能杀一个bi的话,

 设红利总共sum,如果已经能把所有人杀完,则直接 ans1=n,ans2=0,否则,把其余人按ai排序贪心。

为什么呢?

如果能杀一个Bi非零的,必然是,杀死所有Bi,并获得红利,才是优的,因为每多杀一个Bi,要么红利不变,要么增加,但是问题在于Bi要用红利杀还是用耐久度杀,我们可以这样处理,直接相当于把所有红利到手,然后把除了最小的哪个bi去掉,其他人排序,从小的开始杀,必然合法。   

在杀得过程中,我们只需要保证bi全被杀掉即可,而本来红利就》num of bi非零的人数,还用耐久杀了,则保证bi全被杀掉,并且尽可能把耐久度花费小的杀掉



#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=0.000001;
struct node
{
    int a,b;
};
node tt[100005];
bool cmp(node a,node b)
{
    return a.a<b.a;
}
int main()
{
    int cnt=1;

    int t;
    cin>>t;
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        int sumb=0;
        int mm=m;
        int mini,minb=2e9;
        for (int i=1; i<=n; i++)
        {
            scanf("%d%d",&tt[i].a,&tt[i].b);
            if (tt[i].b)
            {
                sumb+=tt[i].b;
                if (tt[i].a<minb)
                {
                    minb=tt[i].a;
                    mini=i;
                }
            }
        }
        int ans1,ans2;
        if (m>=minb)
        {
            if (sumb+1>=n)
            {
                ans1=n;
                ans2=minb;
            }
            else
            {
                swap(tt[mini],tt[n]);
                sort(tt+1,tt+n,cmp);
                m-=minb;
                ans1=sumb+1;
                for (int i=1; i<n&&ans1<n; i++)
                {
                    if (m>=tt[i].a)
                    {
                        ans1++;
                        m-=tt[i].a;
                    }
                    else break;
                }

                ans2=mm-m;

            }
        }
        int ans3=0,ans4;
        m=mm;
        sort(tt+1,tt+n+1,cmp);
        for (int i=1; i<=n; i++)
        {
            if (m>=tt[i].a)
            {
                ans3++;
                m-=tt[i].a;
            }
            else break;
        }

        ans4=mm-m;

        if (ans3>ans1)
        {
            ans1=ans3;
            ans2=ans4;
        }
        else if (ans3==ans1)
            ans2=min(ans2,ans4);
        printf("Case %d: %d %d\n",cnt++,ans1,ans2);
    }



    return 0;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值