这是第一场多校的题目,当时是我在做,没出--。
检讨下,当时思路是对了的,用最大的任务,去匹配最小但刚好满足它的机器--,但是由于其他各种原因,写出的代码超时了。赛后想了下,比赛时for循环里面嵌套了个while循环,超时就在这里。其实是完全可以预处理的,我觉得是六月没a题,导致以往很多思路常识,都忘了----坑爹啊,于是改了下,将嵌套的for循环用队列预处理掉了....ac
题意:有n台机器,m台任务,每个任务和机器都有两个属性,一个是时间属性,一个是等级属性,只有当一台机器的两个属性都大于等于一个任务的两个属性时,才可以将这个任务完成。完成一个任务一颗得到的价值:时间*500+等级*2,题目是要求在完成最多的任务的情况下的最大价值。
思路:按时间从大到小排序,同时要是时间相等,则等级高的应该排在前面,由于只有100个等级,那么对等级开个队列queue<node>q[105],这样的话,每个队列里面第一个元素装的应该是对应的这个等级的最大时间的机器,第二个应该是次大的,并依次类推。然后用任务来匹配机器--。先是最大的任务,找到它所需要的最低等级,如果最低等级不能匹配它,则等级往上增加,直到找到一个与之匹配的,或者所有的机器都不能匹配它--。要是找到了一个与之匹配的机器,那么需要删掉这个机器--
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<algorithm> using namespace std; typedef __int64 ss; #define inf 100005 struct node { ss a,b; }s[inf],t[inf]; ss n,m; queue<ss>q[105]; ss cmp(const node p,const node p1) { if(p.a>p1.a) return 1; else if(p.a==p1.a&&p.b>p1.b) return 1; else return 0; } int main() { while(scanf("%I64d%I64d",&n,&m)>0) { for(ss i=0;i<=100;i++) { while(!q[i].empty()) q[i].pop(); } for(ss i=0;i<n;i++) { scanf("%I64d%I64d",&s[i].a,&s[i].b); } for(ss i=0;i<m;i++) { scanf("%I64d%I64d",&t[i].a,&t[i].b); } sort(s,s+n,cmp); sort(t,t+m,cmp); for(ss i=0;i<n;i++) { ss tmp=s[i].a,tmp1=s[i].b; q[tmp1].push(s[i].a); } ss k=0,ans=0; for(ss i=0;i<m;i++) { ss a=t[i].a; ss b=t[i].b; while(1) { if(b>100) break; while(q[b].size()==0&&b<=100) b++; if(b>100) break; ss tmp=q[b].front(); if(tmp<a) b++; else break; } if(b>100) continue; k++; ans+=500*t[i].a+2*t[i].b; q[b].pop(); } printf("%I64d %I64d\n",k,ans); } return 0; }
hdu4864
时间: 2024-11-05 22:48:00