HDU 4864 Task 贪心 好题

                  Task

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4103    Accepted Submission(s): 1077

Problem Description

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 2

100 3

100 2

100 1

Sample Output

1 50004

Author

FZU

Source

2014 Multi-University Training Contest 1

题意:有m个任务,每一个任务有完成需要的时间,和完成的难度水平level

现在有n台机器,每台任务有工作的最大时间,和可以完成的任务的最大难度。

完成一个任务可以获得奖金time*500+level*2

要求:

机器可以完成的条件是:最大时间>=任务的时间,最大level>=任务的level

每个任务只能由一台机器完成

每台机器只能完成一个任务

现在要求:完成尽量多的任务,多种情况的时候,尽量使得奖金最多。

一看就觉得是贪心

这道题,开始的思路:

优先按奖金大到小排序,再2个下标一次在任务和机器移动,这样不是最优解

这样有3个因素:奖金,时间,level,无法贪心

后来发现:时间的数据范围,和level的数据范围很特殊,可以证明:

若优先按时间从大到小排序后,前面的任务和后面的任务,无论level的差距多大,完成前面的任务的奖金一定不低于完成后面的任务。

这样通过排序后,我们需要考虑的因素就只有2个:时间,level

这样就把奖金的影响消去了。

所以:我们可以先把任务和机器按时间大到小排序,时间相同按照level大到小排序。

这样只要我们考虑任务的时候,从大到小,就可以保证奖金一定是最多的。

接着:我是用2个下标分别指向任务的开头和机器的开头,然后不断后移,贪心选取可以完成的任务。

但是这样无法得到最优,给组数据

任务:(90,90),(50,100)

机器:(100,100),(90,90)

所以要怎么办呢?

根据贪心:我们排序任务和机器后:应该做的是:

对于每一个任务:找出可以完成这个任务的所有机器中,level最低的那一个来完成。

因为这些机器的时间满足这个任务,必然也满足这个任务后面所有的任务,但是可能后面的任务的level非常大

所以我们要尽量保留level大的机器以备后面任务的使用。

这道题自己收获还是挺大的,数据要仔细研究,可能会有一些隐含条件。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4
 5 using namespace std;
 6
 7 const int maxn=100000+10;
 8
 9 struct Node
10 {
11     int time,level;
12 };
13
14 Node mac[maxn];
15 Node task[maxn];
16
17 bool cmp(Node a,Node b)
18 {
19     if(a.time==b.time)
20         return a.level>b.level;
21     return a.time>b.time;
22 }
23
24 inline int ret(int x)
25 {
26     return task[x].time*500+task[x].level*2;
27 }
28
29 int cnt[105];
30
31 int main()
32 {
33     int M,N;
34     while(~scanf("%d%d",&N,&M))
35     {
36         for(int i=1;i<=N;i++)
37         {
38             scanf("%d%d",&mac[i].time,&mac[i].level);
39         }
40
41         for(int i=1;i<=M;i++)
42         {
43             scanf("%d%d",&task[i].time,&task[i].level);
44         }
45
46         sort(mac+1,mac+N+1,cmp);
47         sort(task+1,task+M+1,cmp);
48
49         int ans=0;
50         long long sum=0;
51
52         memset(cnt,0,sizeof(cnt));
53
54         int j=1;
55         for(int i=1;i<=M;i++)
56         {
57             while(j<=N&&mac[j].time>=task[i].time)
58             {
59                 cnt[mac[j].level]++;
60                 j++;
61             }
62             for(int k=task[i].level;k<=100;k++)
63             {
64                 if(cnt[k])
65                 {
66                     cnt[k]--;
67                     sum+=(long long)ret(i);
68                     ans++;
69                     break;
70                 }
71             }
72         }
73         printf("%d %I64d\n",ans,sum);
74     }
75     return 0;
76 }

时间: 2024-10-18 22:38:51

HDU 4864 Task 贪心 好题的相关文章

2014多校第一场D题 || HDU 4864 Task (贪心)

题目链接 题意 : 用N台机器,M个任务,每台机器都有一个最大工作时间和等级,每个任务有一个需要工作时间和一个等级.如果机器完成一个任务要求是:机器的工作时间要大于等于任务的时间,机器的等级要大于等于任务的等级.一台机器只能完成一个任务,一个任务只能被一台机器完成.每个机器完成一个任务公司能够获得500*xi+2*yi (此处xy都是指被完成的任务的).输出所有机器能完成的最多任务数,和最大盈利. 思路 :贪心,自己做的时候想了各种排序都不对,没有考虑到500*xi+2*yi 这个公式的重要性.

HDU 4864 Task (贪心+STL多集(二分)+邻接表存储)(杭电多校训练赛第一场1004)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4864 解题报告:有n台机器用来完成m个任务,每个任务有一个难度值和一个需要完成的时间,每台机器有一个可以工作的最长时间和一个可以完成的任务的难度的最大值, 一台机器能完成一个任务的条件是这台机器的最长工作时间和能完成任务的难度值必须都大于等于这个任务,而且一台机器最多完成一个任务,假设一个任务的时间为t,难度值为x,那么完成这个任务可以赚到的钱 money = 500 * t + 2 * x; 现在

HDU 4864 Task(贪心)

HDU 4864 Task 题目链接 题意:有一些机器和一些任务,都有时间和等级,机器能做任务的条件为时间等级都大于等于任务,并且一个任务只能被一个机器做,现在求最大能完成任务,并且保证金钱尽量多 思路:贪心,对于每个任务,时间大的优先去匹配,时间相同的,等级大的优先去匹配,因为时间占得多,时间多1就多500,而等级最多才差200.然后匹配的时候,尽量使用等级小的去匹配,而时间只要大于它的都可以用,因为是按时间优先,所以如果该时间能匹配大的,其他肯定也能匹配,那么肯定优先匹配大的,所以只要在等级

hdu 4864 Task (贪心 技巧)

题目链接 一道很有技巧的贪心题目. 题意:有n个机器,m个任务.每个机器至多能完成一个任务.对于每个机器,有一个最大运行时间xi和等级yi, 对于每个任务,也有一个运行时间xj和等级yj.只有当xi>=xj且yi>=yj的时候,机器i才能完成任务j,并获得 500*xj+2*yj金钱.问最多能完成几个任务,当出现多种情况时,输出获得金钱最多的情况. 分析:机器和任务都按照先拍x从大到小,再拍y从大到小的顺序.然后遍历任务,注意f[]数组的作用,f[]数组标 记大于当前任务时间的机器的等级个数,

HDU 4864 Task(2014多校--贪心)

Task 比赛当时思路想的差不多,感觉能过的,该处理的也都处理到了,最后还是没过,可能是二分写错了吧-.- 大意:给你n个机器,m个要完成的任务,每个机器跟任务都有两个属性,机器是最大工作时间跟等级,任务是需要工作的时间跟等级.完成一个任务可以得到500*(工作时间)+2*(等级)的报酬.完成任务的条件是机器的工作时间满足任务的需要,等级要大于等于任务的等级,一个机器只能用一次,一个任务也只能用一个机器去完成.需要进行策略选择,使得完成更多的任务. 思路:开始想的就是贪心,也想到了贪心的时候时间

hdu 4864 Task (贪心)

# include <stdio.h> # include <algorithm> # include <string.h> using namespace std; struct node { int t; int v; int yy; }; struct node a[100010],b[100010]; bool cmp(node a1,node a2) { if(a1.t==a2.t)//先按时间从大到小 return a1.v>a2.v;//再按水平从大

HDU 4864 Task(基本算法-贪心)

Task Problem Description 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

hdu 4869 Task(贪心)

题目链接:hdu 4869 Task 题目大意:有n台机器,m个任务,每个机器和任务都有有xi和yi,要求机器的xi,yi均大于等于任务的xi和yi才能执行任务.每台机器一天只能执行一个任务.要求完成的任务数尽量多,并且说金额尽量大.完成每个任务的金额为xi?500+yi?2 解题思路:贪心,mach[i][j]表示等级为i,时间为j的机器数量,task[i][j]表示等级为i,时间为j的机器数量.每次优先减少i,因为对应等级减少100,对应的金额代价也不会减少超过500(即时间减少1). 每次

hdu 4864 Task(贪婪啊)

主题链接:pid=4864">http://acm.hdu.edu.cn/showproblem.php?pid=4864 Task Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1346    Accepted Submission(s): 336 Problem Description Today the company h