zoukankan      html  css  js  c++  java
  • Exams(二分求左界+贪心)

    用力戳我直达原题:D - Exams

    题意:

    有N天和M门课程。

    接下来给你N天的行为,0表示这一天只能预习,[1,m]表示这一天可以考这门课(当然这一天你也可以选择不考或者预习)。

    接下来给你M个数cost[i],代表第i门课需要预习cost[i]天才能PASS。

    求从第一天起算,最少需要几天才能PASS所有功课,如果N天都PASS不了,则输出-1。

    做法:

    1.先判断用N天能否PASS,不能就输出-1。

    2.low = m, high = n。求左界。

    3-1 judge的时候,一门课肯定越慢考越容易通过,所以从mid开始找,第一次遇到的功课标记vis[day[i]]。

    3-2 如果day[i]等于0或者day[i]已经访问过了,也就是说这一天能用来复习,sum++;

    3-3 如果sum >= 预习所需要的总时间sum_cost,且所有课程都有安排考试,说明时间充裕,返回true。

    3-4 第一天肯定只能拿来复习不能拿来考试,所以sum初始化为1,遍历从 mid -> 2

    3-5 从mid开始找到第一个不是0的数,因为这些天的复习是无效的,后面无考试了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #include <bits/stdc++.h>
    using namespace std;
    int day[100100];
    int sum_cost = 0;
    bool vis[100100];
    int n, m, x;
    bool judge(int mid) {
        memset(vis, falsesizeof(vis));
        while(day[mid] == 0) mid--;
        int sum = 1;  //累加预习时间
        int tot = 0;  //累加安排考试科目数
        for(int i = mid; i >= 2; i--) {
            int cur = day[i];
            if(vis[cur] || cur == 0) sum++;
            else tot++, vis[cur] = true;
        }
        return (sum >= sum_cost && tot == m);
    }
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) scanf("%d", day+i);
        for(int i = 1; i <= m; i++) scanf("%d", &x), sum_cost += x;  //累计最终需要多少天
        if(judge(n) == false) {
            puts("-1");
            return 0;
        }
        int low = m, high = n;
        while(low < high) {
            int mid = low + high >> 1;
            if(judge(mid)) high = mid;
            else low = mid + 1;
        }
        printf("%d ", high);
    }
  • 相关阅读:
    git删除目录,且保留本地的
    gitpush 免密码
    git常用操作
    ubuntu安装Nodejs
    ubuntu如何配置samba
    用AI将png转成svg做字符图标教程
    windows server 2012设置远程连接断开后自动注销
    windows 2012执行计划任务错误:操作员或系统管理员拒绝了请求(0x800710E0)
    删除节点
    代理 XP”组件已作为此服务器安全配置的一部分被关闭。系统管理员可以使用 sp_configure 来启用“代理 XP”。
  • 原文地址:https://www.cnblogs.com/bestwzh/p/6731051.html
Copyright © 2011-2022 走看看