1. 程式人生 > >HDU 4864 貪心

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);
    }
}