hdu 1789 Doing Homework again 贪心+优先队列

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL __int64
const int maxn=1010;
struct node{
    int a,b;
    bool operator <(const node x)const{
        return b>x.b;
    }
}e[maxn],f[maxn];
int cmp(node x,node y)
{
    if(x.a==y.a)return x.b>y.b;
    return x.a<y.a;
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int i,j,k,n;
        cin>>n;
        for(i=0;i<n;i++)
            cin>>e[i].a;
        for(i=0;i<n;i++)
            cin>>e[i].b;
        sort(e,e+n,cmp);
        priority_queue<node>q;
        int t=0,ans=0,st=0,en=0;
        node p;
        for(i=0;i<n;i++)
        {
            if(e[i].a>t){q.push(e[i]);t++;}
            else
            {
                p=q.top();
                if(p.b<e[i].b)
                {
                    ans+=p.b;
                    q.pop();
                    q.push(e[i]);
                }
                else
                    ans+=e[i].b;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
/*
    贪心。
    根据交作业的时间排序。
    然后根据顺序一天天安排过去,如果有那个不符(即安排的天大于最迟交作业的时间),那就判断前面符合的情况中最小的罚时p,和这个符合的作业的罚时q比。
若p<q,则用这个不符合的作业顶替掉罚时最小的符合作业(由于排序,所以必定能顶替),然后继续安排直到下个不符出现,循环至结束。
    找最小值可以用优先队列。
    例:
    1 1 2 3 2
    2 3 5 4 9
    排序后
    1 1 2 2 3
    3 2 9 5 4
    (1,3) 第一天,符合,安排(1,3),最小值为3
    (1,2) 第二天,不符,又2<3,所以不顶替。
    (2,9) 第二天,符合,安排(2,9),最小值为3
    (2,5) 第三天,不符,有5>3,所以顶替,最小值为5
    (3,4) 第三天,符合,安排(3,4)
    最终安排为第一天:(2,5),第二天:(2,9),第三天(3,4),答案为2+3=5
*/

你可能感兴趣的:(hdu 1789 Doing Homework again 贪心+优先队列)