[贪心][51nod] 最高的奖励

1163 最高的奖励

有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励。在结束时间之前完成该任务,就可以获得对应的奖励。完成每一个任务所需的时间都是1个单位时间。有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍。求能够获得的最高奖励。

输入

第1行:一个数N,表示任务的数量(2 <= N <= 50000)
第2 - N + 1行,每行2个数,中间用空格分隔,表示任务的最晚结束时间E[i]以及对应的奖励W[i]。(1 <= E[i] <= 10^9,1 <= W[i] <= 10^9)

输出

输出能够获得的最高奖励。

输入样例

7
4 20
2 60
4 70
3 40
1 30
4 50
6 10

输出样例

230

解法:

按任务结束时间排序, O(n)向后扫描, 维护一个长度为当前可选的总任务量的最优解

则有, 若新任务比当前总任务还靠后, 则直接添加, 对任务不影响。

当前任务结束时间和当前总任务量相同时, 则必有可以替换掉当前最优解中的最小值达到更优。(因为此任务替换于当前最优解中的任何任务都满足题意)

因此最终求得最优解

可以用优先队列维护 总复杂的O(nlongn)

typedef long long ll;

const int MAXN = 1e6 + 10;

struct node
{
    int endtime, val;
}arr[MAXN];

bool cmp(node a, node b)
{
    return a.endtime < b.endtime;
}

int main()
{
    //ios::sync_with_stdio(false);
    //cin.tie(0);     cout.tie(0);
    //freopen("D://test.in", "r", stdin);
    //freopen("D://test.out", "w", stdout);

    int n;

    cin>>n;

    for(int i = 0; i < n; i++)
    {
        cin >> arr[i].endtime >> arr[i].val;
    }

    sort(arr, arr + n, cmp);

    priority_queue <ll, std::vector<ll>, greater<ll> > PQ;

    int len = 0;

    for(int i = 0; i < n; i++)
    {
        if(arr[i].endtime > len)
        {
            PQ.push(arr[i].val);
            ++len;
        }

        else
        {
            if(arr[i].val > PQ.top())
            {
                PQ.pop();

                PQ.push(arr[i].val);
            }
        }
    }

    ll ans = 0;

    while(!PQ.empty())
    {
        ans += PQ.top();
        PQ.pop();
    }

    cout<<ans<<'\n';


    
    return 0;
}

 

 

posted @ 2019-03-27 13:43  张浦  阅读(121)  评论(0编辑  收藏  举报