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 Bi after Ai 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.
  1≤N≤105
  1≤M≤105
  1≤Ai≤105
  1≤Bi≤104
Input
  Input is given from Standard Input in the following format:
  N M
  A1 B1
  A2 B2
   ⋮
  AN BN
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.

题意

  给定n份工作,第 i 工作需要工作 Ai 天才能收入 Bi ,你每天可以开始一份工作,但是每份工作只能做一次,问你 m 天的最大收入

思路

  首先只要这个工作的需要时间 <= m,很明显,最后一天一定是在耗时为1的里面找最优解,而最后两天是在耗时为 1 和 2 里找最优解,以此类推……
  开一个优先队列,从 1~m 暴一遍即可

#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll inf = 0x3f3f3f3f3f3f3f;
const int maxn = 100100;
vector<int> p[maxn];	//分类存储
priority_queue<int> q;	//找最优情况
int main(void)
{
    int n,m;
    int a,b;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a,&b);
        p[a].push_back(b);
    }
    int ans = 0;
    for(int i=1;i<maxn;i++) sort(p[i].begin(),p[i].end());	//排序
    for(int i=1;i<=m;i++){
        for(int j=0;j<p[i].size();j++){
            q.push(p[i][j]);	//入队
        }
        if(!q.empty()){
            ans += q.top();	//找最优
            q.pop();	//出队
        }
    }
    printf("%d\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逃夭丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值