HDU 4864 贪心

要求:有n台机器和m个任务,并且每台机器和每个任务都带有一个时间标记和一个等级标记,只有机器的两个标记都大于任务时才能进行该任务。最大等级不超过100,完成一个任务获得钱数为500*时间+2*等级。一台机器一天只能完成一个任务,求完成最大任务数,若有多解,取赚钱数最多的。

方法:贪心。注意T。

1.因为钱数的算式和等级的范围表明,时间为优先考虑项,若任务A的时间比B长,那么A的赚钱数一定比B多。

2.将任务按时间从大到小排序,时间相同时等级从大到小排序。将机器按时间从大到小排序。

3.贪心逻辑是:按照任务顺序已是钱数最多的策略,因此需要选用尽可能小的等级数,较大的等级数机器供其他任务使用。

4.伪代码如下:

for(遍历各个任务)

{

 while(找到时间不小于任务的所有机器)//机器

 {

  用s数组存储等级;

 }

for(从当前任务的等级到100遍历各个等级)//等级

{

 若s数组存有这个等级,则计数并钱加上。

}

}

#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
struct machine
{
 int time1,level;
};
struct task
{
 int x,y;
};
machine machines[100005];
task tasks[100005];
bool cmp1(machine c,machine d)
{
 return c.time1>d.time1;
}
bool cmp2(task a,task b)
{
 if(a.x>b.x) return 1;
 else if(a.x<b.x) return 0;
 else return a.y>b.y;
}
int main()
{
    int i,j,k,n,m,cnt,s[200];
    long long money;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
     cnt=0,money=0;
     memset(s,0,sizeof(s));
     for(i=0;i<n;i++)
     {
      scanf("%d%d",&machines[i].time1,&machines[i].level);
     }
     for(i=0;i<m;i++)
        scanf("%d%d",&tasks[i].x,&tasks[i].y);
     sort(machines,machines+n,cmp1);
     sort(tasks,tasks+m,cmp2);
     j=0;
     for(i=0;i<m;i++)
     {
      while(j<n&&machines[j].time1>=tasks[i].x)
      {
       s[machines[j].level]++;
       j++;
      }
      for(k=tasks[i].y;k<=100;k++)
      {
       if(s[k]>0)
       {
        s[k]--;
        cnt++;
        money+=(500*tasks[i].x+2*tasks[i].y);
        break;
       }
      }
     }
     printf("%d %lld\n",cnt,money);
    }
}






猜你喜欢

转载自blog.csdn.net/Irving0323/article/details/81939562