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
#include
#include
#include
#include
#include
#include
#include
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;
}

你可能感兴趣的:(思维)