2014杭电多校联合第一场Task(贪心+STL使用)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4864

题意:某公司有m个任务需要完成。第i个任务需要xi的时间来完成。同时,该任务还有一个难度系数level yi。如果一个机器的难度系数小于level yi,

则该机器不能处理该任务。如果该公司完成了一个任务,则能获得500*xi+2*yi的收益。

该公司有n台机器,每个机器有一个最大工作时间xi,该时间只有大于任务需要的时间且该机器的难度系数大于任务的难度系数时,该机器才能处理

该任务。 每个机器每天只能处理一个任务。

求该公司能获得的最大收益。


思路:贪心。我觉得这道题贪心的时候,很容易想当然,认为机器的时间和等级尽量大去满足一个任务。

也就是说,需要对机器的时间和等级按照降序排列,对任务也做同样处理。然后,再去一个个对应。而这样

是错误的。以下几组数据可以验证这个方法的错误:

machine            task

100 6               100 3

100 3               50 5

——————————

200 2               150 2

150 10             100 10

——————————

70 4                  40 6

30 2                   40 3

正确的方法是:对于价值c=500*xi+2*yiyi最大影响100*2<500,所以就是求xi总和最大。可以先对机器和任务的时间从大到小排序。

从最大时间的任务开始,找出满足任务时间要求的所有机器,从中找出等级最低且满足任务等级要求的机器匹配。依次对任务寻找满足要求的机器。

(以上内容来自杭电官方解题报告)加粗的那句话是关键。

贪心准则找到了,下面就是怎么找这个等级最低的机器的问题了。一般找法就是暴力啦,果断TLE。然后想到要用二分查找。但是在匹配过程中,机器是

要被删除的,这样就不能实现一般的二分了(用数组存储的)。

然后,就用STL了。。这个具体看程序吧。



#include<cstdio>
#include<string.h>
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#define MAX 100005
using namespace std;
int n,m;
map<int,int> mapp;
struct machine
{
    int minute,level;
}mach[MAX];
struct Task
{
    int minute,level;
}task[MAX];

int cmp(Task a,Task b)
{
    if(a.minute==b.minute)
        return a.level>b.level;
    return a.minute>b.minute;
}
int cnp(machine a,machine b)
{
    if(a.minute==b.minute)
        return a.level>b.level;
    return a.minute>b.minute;
}
int main()
{
    __int64 money;
    int cnt,i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        money=0;
        cnt=0;
        for(i=0;i<n;i++)
            scanf("%d%d",&mach[i].minute,&mach[i].level);
        for(i=0;i<m;i++)
            scanf("%d%d",&task[i].minute,&task[i].level);
        sort(task,task+m,cmp);
        sort(mach,mach+n,cnp);
        mapp.clear();
        j=0,cnt=0,money=0;
        for(i=0;i<m;i++)
        {
            while(j<n&&mach[j].minute>=task[i].minute)
            {
                mapp[mach[j].level]++;          //把满足时间要求的所有机器选出来
                j++;
            }
            map<int,int>::iterator it=mapp.lower_bound(task[i].level);  //二分查找
            if(it!=mapp.end())
            {
                cnt++;
                money+=(task[i].minute*500)+task[i].level*2;
                int t=it->first;
                mapp[t]--;                              //删除对应的机器,用STL的优势就体现在这里啦
                if(mapp[t]==0)                          //不影响整体
                    mapp.erase(t);
            }
        }
        printf("%d %I64d\n",cnt,money);
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值