• 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
    ",q.size());
    36     }
    37 }
  • 相关阅读:
    MySQL教程115-MySQL查看触发器
    MySQL教程114-MySQL创建触发器
    MySQL教程113-MySQL流程控制语句
    MySQL教程112-MySQL游标的定义及使用
    MySQL教程111-MySQL定义条件和处理程序
    MySQL教程110-MySQL变量的定义和赋值
    MySQL教程109-MySQL调用存储过程和函数
    MySQL教程108-MySQL存储函数
    mysql 启动关闭流程
    mysql 连接管理工具
  • 原文地址:https://www.cnblogs.com/loganlzj/p/10119355.html
Copyright © 2020-2023  润新知