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

时间:2021-10-27 22:16:39

题目链接

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

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

官方题解 :

基本思想是贪心。

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

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm> using namespace std ; struct node
{
int time;
int level ;
} task[] ,mach[] ; int vis[] ; int cmp(const node a,const node b)
{
if(a.time == b.time) return a.level > b.level ;
return a.time > b.time ;
} int main()
{
int N,M ;
while(~scanf("%d %d",&N,&M))
{
for(int i = ; i < N ; i++)
{
scanf("%d %d",&mach[i].time,&mach[i].level) ;
}
for(int i = ; i < M ; i++)
scanf("%d %d",&task[i].time,&task[i].level) ;
sort(mach,mach+N,cmp) ;
sort(task,task+M,cmp) ;
memset(vis,,sizeof(vis)) ;
int cnt = ;
long long ans = ;
for(int i = , j = ; i < M ; i++)
{
while(j < N && mach[j].time >= task[i].time)
{
vis[mach[j].level] ++ ;
j++ ;
}
for(int k = task[i].level ; k <= ; k++ )
{
if(vis[k])
{
vis[k]-- ;
cnt ++ ;
ans += task[i].time * + * task[i].level ;
break ;
}
}
}
printf("%d %I64d\n",cnt,ans) ;
}
return ;
}

鹏哥他们用的STL的set

 #include <iostream>
#include<stdio.h>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
#define LL long long
struct list
{
int x;
int y;
int s;
int leap;
friend bool operator <(const list &a,const list &b)
{
if(a.y!=b.y)return a.y<b.y;
else if(a.x!=b.x)return a.x<b.x;
else return a.leap<b.leap;
}
}node[];
multiset<int>st;
multiset<int>::iterator it;
int sea(int x)
{
if(st.size()==)return ;
it=st.begin();
if(x<(*it))return ;
it=st.lower_bound(x);
if(it==st.end())
{
it=st.end();
it--;
int ans=(*it);
st.erase(it);
return ans;
}
if((*it)==x)
{
st.erase(it);
return x;
}
it--;
int ans=(*it);
st.erase(it);
return ans;
}
void dos(int n)
{
int x=;
LL sum=;
st.clear();
for(int i=;i<=n;i++)
{
if(node[i].leap==)
{
int res=sea(node[i].s);
if(res)
{
x++;
sum+=(LL)res;
}
}
else
{
st.insert(node[i].s);
}
}
cout<<x<<" "<<sum<<endl;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=;i<=n;i++)
{
scanf("%d%d",&node[i].x,&node[i].y);
node[i].leap=;
node[i].s=node[i].x*+node[i].y*;
}
for(int i=n+;i<=n+m;i++)
{
scanf("%d%d",&node[i].x,&node[i].y);
node[i].leap=;
node[i].s=node[i].x*+node[i].y*;
}
sort(node+,node+n+m+);
dos(n+m);
}
return ;
}