贪心 (任务与机器)

来源:互联网 发布:java nio 教程 编辑:程序博客网 时间:2024/06/05 08:48
Today the company has m tasks to complete. The ith task need xi minutes to complete. Meanwhile, this task has a difficulty level yi. The machine whose level below this task’s level yi cannot complete this task. If the company completes this task, they will get (500*xi+2*yi) dollars.
The company has n machines. Each machine has a maximum working time and a level. If the time for the task is more than the maximum working time of the machine, the machine can not complete this task. Each machine can only complete a task one day. Each task can only be completed by one machine.
The company hopes to maximize the number of the tasks which they can complete today. If there are multiple solutions, they hopes to make the money maximum.
Input
The input contains several test cases.
The first line contains two integers N and M. N is the number of the machines.M is the number of tasks(1 < =N <= 100000,1<=M<=100000).
The following N lines each contains two integers xi(0<xi<1440),yi(0=<yi<=100).xi is the maximum time the machine can work.yi is the level of the machine.
The following M lines each contains two integers xi(0<xi<1440),yi(0=<yi<=100).xi is the time we need to complete the task.yi is the level of the task.
Output
For each test case, output two integers, the maximum number of the tasks which the company can complete today and the money they will get.
Sample Input
1 2100 3100 2100 1
Sample Output
1 50004
     题目大意:有一堆机器与一堆任务,每一个机器都有两个参数,能够处理任务的时间与难度(t,d)。又有一些任务,这些任务有各自的时间与难度(t1,d1)。如果某个任务的时间与难度都能够被机器所接受(t>t1&&d>d2),那我们就说这个机器可以将这个任务处理掉,同时此机器不能再处理其他任务,此任务也将无法被其他机器所处理。给你若干任务与若干机器,让你来自由选择,保证最后的收益最大,处理一个任务会获得时间*500+难度*2的金钱收益。那么问题来了(先以任务为考虑对象),如果一个任务可以同时被两台机器所处理,我们怎样选择,我们所做的选择又会怎样影响我们后边任务与机器的分配呢?
解: 其实,题目有三个限制条件,金钱,难度,时间,但是我们总会遇到不少题像这个题一样,有着特殊数据与限定条件,假设我们有两个任务,一个为时间为1,难度为1(min),另一个时间为2,难度为100(max),处理任务一的收益还是会大于任务二,因为500-200>0,所以,我们将任务来一个按时间的递减排序,时间最大的必然会带来最大收益,不用考虑难度,因为难度带来的影响可以忽略不计。为什么会递减排序呢?因为我们想先处理能够给我们带来最大收益的任务吧,如果同一个机器能够处理两个任务,我们必定先择收益大的,因为收益是我们的最终决定条件。我们在为排好序的任务选机器时,将第一个,也就是收益最大的任务(大鱼),我们应该选满足要求条件最低的机器,这样可以保证我们留下更牛的机器来处理别的任务,因为虽然我们在任务的选择上忽略了难度,但是选机器的时候机器所决定的任难度是实实在在的(此时机器也应该按照时间做好递减排列),我们不能忽略,可以举例,有机器参数为 (1000,100)(1000,50),有任务为(1000,49),(999,100),我们为任务(1000,49)选机器时,肯定得选(1000,50),如果选了大的,那么剩下的任务将无法被匹配,本来可以两个任务都搞定,却只搞定了一个,这不是我们想要的结果,所以先满足最小要求时间,再在满足最小时间的同时,在相同的最小时间内选择难度能满足要求但是是所有满足任务难度中最低的一个的机器,这样结果就显而易见。(但是最后我们应该通过代码实现,一开始我自己的答案对,但是AC不了,老是超时,参考了一下别的博主的实现方法,知道了实现一些问题的巧妙方法而不必浪费时间在搜索上,最后代码足足省了N行)下面是AC代码,我自己习惯动态申请数组,然后再动态释放,感觉这样保持了选择局限的最优性,可是有时候就是会出错,不如直接开一个满足题目要求的最大区间数组。
#include <iostream>#include<cstring>#include <algorithm>using namespace std;typedef struct contains{   int time;   int level;}contain;bool cmp (contain a,contain b){if (a.time==b.time)return a.level>b.level;return a.time>b.time;}int main (){contain *m,*t;long long i,j,money=0,k,a,b,flag=0,count=0,flag1=0;int c[120]={0};while (scanf("%lld%lld",&a,&b)!=EOF){m=new contain[a];t=new contain[b];for (i=0;i<a;i++)cin>>m[i].time>>m[i].level;for (i=0;i<b;i++)cin>>t[i].time>>t[i].level;sort (m,m+a,cmp);sort (t,t+b,cmp);j=0;    for (i=0;i<b;i++){while (m[j].time>=t[i].time&&j<a){c[m[j].level]++;j++; }for (k=t[i].level;k<=100;k++){if(c[k]){count++;c[k]--;money+=500*t[i].time+2*t[i].level;break;}}}  printf("%lld %lld\n",count,money);money=0;count=0;    delete [] m;    delete [] t;    memset (c,0,sizeof(c));    }    return 0;}
原创粉丝点击