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(可选工作方案),m(天数)
接下来的n 行 An Bn 表示在今天做此工作 An 天后可以领取工资Bn;
分析:
此题用到贪心思想,开始分析时认为是背包问题,看完题解后明白可以使用贪心的思想来解此题。m天数,可以倒着来算,将满足在倒着数1,2 ,3~~m天工作时最大工资求和即可。可利用优先队列将满足工作天数的工资入队,再取出队首最大工资求和并去除即可;
代码
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
struct node{
int a,b;
}s[maxn];
bool cmp(node a,node b)
{
return a.a<b.a;
}
int main()
{
int n,m;
int ant=0;
ll ans=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%d%d",&s[i].a,&s[i].b);
}
priority_queue<int>q;
sort(s,s+n,cmp);//以发工资天数排序
for(int i=1;i<=m;i++)
{
while(s[ant].a<=i&&ant<n)//将满足条件工作工资入队
{
q.push(s[ant].b);
ant++;
}
if(!q.empty())//取出队首最大工资
{
ans+=q.top();
q.pop();
}
}
printf("%lld\n",ans);
return 0;
}