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

题目链接

题意 : 用N台机器,M个任务,每台机器都有一个最大工作时间和等级,每个任务有一个需要工作时间和一个等级。如果机器完成一个任务要求是:机器的工作时间要大于等于任务的时间,机器的等级要大于等于任务的等级。一台机器只能完成一个任务,一个任务只能被一台机器完成。每个机器完成一个任务公司能够获得500*xi+2*yi (此处xy都是指被完成的任务的)。输出所有机器能完成的最多任务数,和最大盈利。

思路 :贪心,自己做的时候想了各种排序都不对,没有考虑到500*xi+2*yi 这个公式的重要性。。。。把每个任务找出能完成的机器,用最接近的机器去做任务,保证最后的结果最大

官方题解 :

基本思想是贪心。

对于价值c=500*xi+2*yiyi最大影响100*2<500,所以就是求xi总和最大。可以先对机器和任务的时间从大到小排序。从最大时间的任务开始,找出满足任务时间要求的所有机器,从中找出等级最低且满足任务等级要求的机器匹配。依次对任务寻找满足要求的机器。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <algorithm>
 5 
 6 using namespace std ;
 7 
 8 struct node
 9 {
10     int time;
11     int level ;
12 } task[100010] ,mach[100010] ;
13 
14 int vis[110] ;
15 
16 int cmp(const node a,const node b)
17 {
18     if(a.time == b.time) return a.level > b.level ;
19     return a.time > b.time ;
20 }
21 
22 int main()
23 {
24     int N,M ;
25     while(~scanf("%d %d",&N,&M))
26     {
27         for(int i = 0 ; i < N ; i++)
28         {
29             scanf("%d %d",&mach[i].time,&mach[i].level) ;
30         }
31         for(int i = 0 ; i < M ; i++)
32             scanf("%d %d",&task[i].time,&task[i].level) ;
33         sort(mach,mach+N,cmp) ;
34         sort(task,task+M,cmp) ;
35         memset(vis,0,sizeof(vis)) ;
36         int cnt = 0 ;
37         long long ans = 0 ;
38         for(int i = 0 , j = 0 ; i < M ; i++)
39         {
40             while(j < N && mach[j].time >= task[i].time)
41             {
42                 vis[mach[j].level] ++ ;
43                 j++ ;
44             }
45             for(int k = task[i].level ; k <= 100 ; k++ )
46             {
47                 if(vis[k])
48                 {
49                     vis[k]-- ;
50                     cnt ++ ;
51                     ans += task[i].time * 500 + 2 * task[i].level ;
52                     break ;
53                 }
54             }
55         }
56         printf("%d %I64d
",cnt,ans) ;
57     }
58     return 0 ;
59 }
View Code

鹏哥他们用的STL的set

 1 #include <iostream>
 2 #include<stdio.h>
 3 #include<set>
 4 #include<vector>
 5 #include<algorithm>
 6 using namespace std;
 7 #define LL long long
 8 struct list
 9 {
10     int x;
11     int y;
12     int s;
13     int leap;
14     friend bool operator <(const list &a,const list &b)
15     {
16         if(a.y!=b.y)return a.y<b.y;
17         else if(a.x!=b.x)return a.x<b.x;
18         else return a.leap<b.leap;
19     }
20 }node[220000];
21 multiset<int>st;
22 multiset<int>::iterator it;
23 int sea(int x)
24 {
25     if(st.size()==0)return 0;
26     it=st.begin();
27     if(x<(*it))return 0;
28     it=st.lower_bound(x);
29     if(it==st.end())
30     {
31         it=st.end();
32         it--;
33         int ans=(*it);
34         st.erase(it);
35         return ans;
36     }
37     if((*it)==x)
38     {
39         st.erase(it);
40         return x;
41     }
42     it--;
43     int ans=(*it);
44     st.erase(it);
45     return ans;
46 }
47 void dos(int n)
48 {
49     int x=0;
50     LL sum=0;
51     st.clear();
52     for(int i=1;i<=n;i++)
53     {
54         if(node[i].leap==1)
55         {
56             int res=sea(node[i].s);
57             if(res)
58             {
59                 x++;
60                 sum+=(LL)res;
61             }
62         }
63         else
64         {
65             st.insert(node[i].s);
66         }
67     }
68     cout<<x<<" "<<sum<<endl;
69 }
70 int main()
71 {
72     int n,m;
73     while(~scanf("%d%d",&n,&m))
74     {
75         for(int i=1;i<=n;i++)
76         {
77             scanf("%d%d",&node[i].x,&node[i].y);
78             node[i].leap=1;
79             node[i].s=node[i].x*500+node[i].y*2;
80         }
81         for(int i=n+1;i<=n+m;i++)
82         {
83             scanf("%d%d",&node[i].x,&node[i].y);
84             node[i].leap=0;
85             node[i].s=node[i].x*500+node[i].y*2;
86         }
87         sort(node+1,node+n+m+1);
88         dos(n+m);
89     }
90     return 0;
91 }
View Code
原文地址:https://www.cnblogs.com/luyingfeng/p/3864722.html