AlvinZH的学霸养成记II——1032

AlvinZH的学霸养成记II

时间限制:1000ms   内存限制:65536kb

 

题目描述

由于校赛签到题而迟到的养成记II,你注意到了吗?

AlvinZH妄图成为一个学霸,他想学很多很多的课。

教务网上的课都太固定了,AlvinZH准备去慕课上选几门课学习提高一下姿势。每门课程依然有持续时间 dd ,虽然没有固定开始时间,却有结课时间 ee ,过了DDL后不可再学习此课程。AlvinZH只有在连续学习完一门课后,才会开始下一门课的学习,AlvinZH必须得在结课之前完成每门课的学习。

AlvinZH想知道他最多能学习多少门课,你来帮帮他吧!

注:AlvinZH最早可以从第一天开始学习,结课时间e代表将在第e天结课。

输入

输入包含多组数据。

每组数据第一行为课程数n(0<n≤10^5)。

接下来n行,每行两个整数d和e,代表课程持续时间和结课DDL(0<d,e≤10^6)。

输出

对于每组数据,输出一行,为AlvinZH最多可学习的课程数。

输入样例

3
1 1
2 2
3 3

输出样例

1

HINT

你想到优先队列了吗?

HINT2

可参考Leetcode 630. Course Schedule III

题目分析

  1. 考虑到这里有分别的结束限制,很直观想法是结束时间靠前的先处理。所以,按照DDL排序,按序处理每门课。
  2. 这时候考虑,某个结束时间靠前的在某个DDL之前放可能是忧的,但是他可能影响DDL靠后的课程的放置导致之后不优。但是,对于当前处理的DDL,显然放置的科目都是DDL更靠前的。所以删除之前的课并不影响结果。
  3. 思考到这步结果就出来了,对于某个课的DDL,假设前一个的最多放置方案用了Tot的时间,当前课需要c,如果Tot+c<=DDL则直接放置,否则选出曾经放置的时间最长的课,对比当前的课:如果当前课的代价小,则删除选出的课,放进当前的课;否则不变。二叉堆维护即可。

具体思路

贪心+优先队列优化
设置st为当前时间
按结束时间e排序,依次选择,并将持续时间d入队,更新st,若st>e则说明无法安排这门课,但此时不是将该门课出队,而是将队列内d最长的课出队(易知能保证出队后st<e,且能使st更小,因此这样做是合理的).

出现的问题:一开始优先队列的类型建的结构体的,觉得逻辑和实现都没问题,但就一直WA。换了一种写法,用int的优先队列就过了。然而两种写法贪心部分的逻辑是一样的,初步判定问题在于sort或优先队列的实现上,最后发现sort时比较的是结构体的e参量,而优先队列中比较的是d参量,wa的代码只用e的关系重载了结构体的<符,增加了cmp后过了

AC代码

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<queue>
 5 using namespace std;
 6 struct Lesson{
 7     int d,e;
 8     bool operator < (const Lesson &a) const{        //重载<,l1<l2为真当且仅当l1.e<l2.e,此时优先队列生成最大堆
 9         return d<a.d;
10     }
11 };
12 bool cmp(Lesson l1,Lesson l2){
13     return l1.e<l2.e;
14 }
15 const int maxn=100007;
16 priority_queue<Lesson> q;
17 Lesson l[maxn];
18 int main(){
19     int n;
20     while(~scanf("%d",&n)){
21         int st=0;
22         for(int i=0;i<n;++i){
23             scanf("%d%d",&l[i].d,&l[i].e);
24         }
25         sort(l,l+n,cmp);
26         while(!q.empty()) q.pop();
27         for(int i=0;i<n;++i){
28             st+=l[i].d;
29             q.push(l[i]);
30             if(st>l[i].e){
31                 st-=q.top().d;
32                 q.pop();
33             }
34         }
35         printf("%d\n",q.size());
36     }
37 }

猜你喜欢

转载自www.cnblogs.com/loganlzj/p/10119355.html