HDU 4864 貪心
阿新 • • 發佈:2018-12-04
要求:有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); } }