Summer Vacation 贪心

Problem Statement
There are N one-off jobs available. If you take the i-th job and complete it, you will earn the reward of B_i after A_i days from the day you do it.

You can take and complete at most one of these jobs in a day.

However, you cannot retake a job that you have already done.

Find the maximum total reward that you can earn no later than M days from today.

You can already start working today.

Constraints
All values in input are integers.

Input
Input is given from Standard Input in the following format:

Output
Print the maximum total reward that you can earn no later than M days from today.

Sample Input 1
3 4
4 3
4 1
2 2
Sample Output 1
5
You can earn the total reward of 5 by taking the jobs as follows:

Take and complete the first job today. You will earn the reward of 3 after four days from today.
Take and complete the third job tomorrow. You will earn the reward of 2 after two days from tomorrow, that is, after three days from today.
Sample Input 2
5 3
1 2
1 3
1 4
2 1
2 3
Sample Output 2
10
Sample Input 3
1 1
2 1
Sample Output 3
0

题意:
一共有n项工作可以做,你一共有k天的时间,每个工作所耗费的时间和所得到的报酬在每一行成对出现;然后你每一天都可以选择一项新的任务,并且同时就行以前的任务;
问 k天下来,最多能获得多少报酬;
思路:
把时间从小到大的排列;然后从第k天倒着来,看剩余i天时能做的任务并且报酬最大是多少;

#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;
const int maxx=1e5+7;
struct node
{
    int t,s;
}bb[maxx];
bool cmp(node a,node b)
{
    return a.t<b.t;
}
int main()
{
    std::ios::sync_with_stdio(false);
    int n,m;
    cin >>n>>m;
    for(int i=0;i<n;i++)
    {
        cin >>bb[i].t>>bb[i].s;
    }
    sort(bb,bb+n,cmp);//将任务的天数从小到大排列;
    priority_queue<int> q;//用优先队列(优先队列把报酬按从大到小排列)
    int ans=0;
    int sum=0;
    for(int i=1;i<=m;i++)
    {
        while(1)
        {
            if(bb[ans].t<=i&&ans<n)//如果当前任务的天数小于剩余的天数,则表示可以完成它;就把他放到队列里面;(为什么都放里面呢,如果剩i天可以完成这些任务,那么剩余i+1天一定可以完成这些任务,所以只需要挑时间短,报酬高的即可)
            {
                q.push(bb[ans].s);
                ans++;
            }
            else break;
        }
        if(q.empty()) continue;
        else sum+=q.top();
        q.pop();
    }
    cout <<sum<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值