CodeForces732D——Exams 详解

  • Exam
  • 题目描述(google翻译)

    • Vasiliy的考试期限将持续n天。他必须通过m门科目的考试。受试者编号为1至m。

      大约每天我们都知道当天可以通过m个科目中的哪一个的考试。也许,有一天你不能通过任何考试。任何一天都不允许通过多个考试。

      每天Vasiliy都可以通过当天的考试(需要一整天)或准备一整天的考试或休息。

      关于每个主题Vasiliy知道一个数字ai - 他准备通过考试号码的天数i。 Vasiliy可以在准备考试时切换科目,没有必要在考试编号i的ai天内连续准备。他可以以任何方式混合考试准备。

      您的任务是确定Vasiliy可以通过所有考试的最短天数,或确定不可能。每次考试都应该通过一次。

  • 输入

    • 第一行包含两个整数n和m(1≤n,m≤105) - 考试期间的天数和科目数。

      第二行包含n个整数d1,d2,…,dn(0≤di≤m),其中di是考试的科目号,如果是 3,就代表可以考第三门。如果di等于0,则不允许在第i天通过任何考试。

      第三行包含m个正整数a1,a2,…,am(1≤ai≤105),其中ai是在通过对象i的考试之前准备所需的天数。

  • 输出
    • 打印一个整数 - Vasiliy可以通过所有考试的最小天数。如果不可能,请打印-1。
  • 样例输入 1
    • 7 2
      0 1 0 2 1 0 2
      2 1
  • 样例输出 1
    • 5
  • 样例输入 2
    • 10 3
      0 0 1 2 3 0 2 0 1 2
      1 1 4
  • 样例输出 2
    • 9
  • 样例输入 3
    • 5 1
      1 1 1 1 1
      5
  • 样例输出 3
    • -1
  • 问题分析
    • 贪心的想,也就是考试往后推,直到最后能考的那一天,如果这样复习时间都不够,那么肯定是过不了的。
    • 那么二分怎么用呢,二分就用在时间上,对于一个输入天数 n,他最迟不能超过 n 天通过考试,否则就不能通过,因此利用二分时间找出答案。
    • 你可能会产生这样的疑问,怎么保证程序在某一门考试的最后期限来临之前将该科目可以利用的时间都用上。这个并不难实现,只需要将每个科目的位置记录下来,比如对于第二组数据,1 首先出现,那么它的位置为 3,记为1 - 3,接下来是 2 - 4,3 - 5,2 - 7,1 - 9,2 - 10,看到了吗,只要 1 后面还有 1,它的位置就会被修改,那我们只需要根据记录的位置信息来判断接下来要考试的科目和所拥有的时间,就可以保证在考试前利用所有可用的时间。
#include <iostream>
#include <cstdio>
#include <cstring> #define Maxn 100001 using namespace std; int day[Maxn],exam[Maxn];
int n,m;
bool deal(int mid); int main()
{ cin>>n>>m;
int i = ;
for(i = ; i <= n; i++)
cin>>day[i];
for(i = ; i <= m; i++)
cin>>exam[i];
int l = ;
int r = n;
int ans = -;
while(r >= l)
{
int mid = (l + r)/;
if(deal(mid))
{
ans = mid;
r = mid - ;
}
else
l = mid + ;
}
cout<<ans;
return ;
} bool deal(int mid)
{
int havetime = ;
int lastday[Maxn];
memset(lastday,-,sizeof(lastday));
int i = ;
for(i = ; i <= mid; i++)
{
if(day[i] != )
{
lastday[day[i]] = i;
}
}
for(i = ; i <= m ; i++)
{
if(lastday[i] == -)
return false;
}
for(i = ; i <= mid; i++)
{
if(day[i] == )
havetime++;
else
{
if(lastday[day[i]] == i)
{
if(havetime >= exam[day[i]])
{
havetime -= exam[day[i]];
}
else
return false;
}
else
havetime++;
}
}
return true;
}

二分算法题目训练(二)——Exams详解的更多相关文章

  1. 二分算法题目训练(一)——Shell Pyramid详解

    HDU2446——Shell Pyramid 详解 Shell Pyramid 题目描述(Google 翻译的) 在17世纪,由于雷鸣般的喧嚣,浓烟和炽热的火焰,海上的战斗与现代战争一样.但那时,大炮 ...

  2. 二分算法题目训练(三)——Anton and Making Potions详解

    codeforces734C——Anton and Making Potions详解 Anton and Making Potions 题目描述(google翻译) 安东正在玩一个非常有趣的电脑游戏, ...

  3. 二分算法题目训练(四)——Robin Hood详解

    codeforces672D——Robin Hood详解 Robin Hood 问题描述(google翻译) 我们都知道罗宾汉令人印象深刻的故事.罗宾汉利用他的射箭技巧和他的智慧从富人那里偷钱,然后把 ...

  4. 【模型推理】量化实现分享二:详解 KL 对称量化算法实现

      欢迎关注我的公众号 [极智视界],回复001获取Google编程规范   O_o   >_<   o_O   O_o   ~_~   o_O   大家好,我是极智视界,本文剖析一下 K ...

  5. ViewPager 详解(二)---详解四大函数

    前言:上篇中我们讲解了如何快速实现了一个滑动页面,但问题在于,PageAdapter必须要重写的四个函数,它们都各有什么意义,在上节的函数内部为什么要这么实现,下面我们就结合Android的API说明 ...

  6. iOS 开发之照片框架详解之二 —— PhotoKit 详解(下)

    本文链接:http://kayosite.com/ios-development-and-detail-of-photo-framework-part-three.html 这里接着前文<iOS ...

  7. iOS 开发之照片框架详解之二 —— PhotoKit 详解(上)

    转载自:http://kayosite.com/ios-development-and-detail-of-photo-framework-part-two.html 一. 概况 本文接着 iOS 开 ...

  8. 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码

    详解C#泛型(二)   一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...

  9. Hexo系列(二) 配置文件详解

    Hexo 是一款优秀的博客框架,在使用 Hexo 搭建一个属于自己的博客网站后,我们还需要对其进行配置,使得 Hexo 更能满足自己的需求 这里所说的配置文件,是位于站点根目录下的 _config.y ...

随机推荐

  1. 多线程面试题之【三线程按顺序交替打印ABC的方法】

    建立三个线程,线程名字分别为:A.B.C,要求三个线程分别打印自己的线程名字,但是要求三个线程同时运行,并且实现交替打印,即按照ABCABCABC的顺序打印.打印10轮,打印完毕控制台输出字符串:&q ...

  2. JQuery 文本框控制验证数字

    $("input[name=XUEFEN]").keypress(function(event) { var keyCode = event.which; if (keyCode ...

  3. Matlab脚本和函数

    脚本和函数 脚本: 特点:按照文件中所输入的指令执行,一段matlab指令集合.运行后,运算过程产生的所有变量保存在基本工作区.可以进行图形输出,如plot()函数. 举例: 脚本文件ex4_15.m ...

  4. 测试winform程序到树莓派运行

    啥也不说了,都在下图中了.winform可以在树莓派上跑了

  5. iOS - FMDB数据库的使用

    下面不废话了直接上代码

  6. 5.JUC之JDK自带锁ReentrantLock

    一.初识 ReentrantLock出身自jdk1.5,中文名:可重入锁 是Java JDK自带独占锁的唯一实现,是synchronized的升级版 1.我们之间有个synchronized 我们已经 ...

  7. Linux:入门基础

    一.操作Linux必知必会基础知识 二.在Linux命令下查看命令帮助信息 三.Linux挂机重启注销命令 四.Linux显示系统IP地址 一.操作Linux必知必会基础知识 1.Linux命令行组成 ...

  8. Luogu P5020 货币系统

    Luogu P5020 货币系统 先把$a$数组排一下序. 从最小的数开始选,显然最小这个数必须选,然后利用完全背包的思想,从$a_i$到最大值筛选一遍,将可以组成的打上标记. 在判断后面的数字时,如 ...

  9. python数据类型:dict(字典)

    一.字典的简单介绍 字典(dict)是python中唯一的一个映射类型.他是以{}括起来的键值对组成. 语法: {key1:value1,key2:value2......} 注意:key必须是不可变 ...

  10. 初识python中的68个内置函数

    内置函数思维导图的链接: https://www.processon.com/view/link/5b72b805e4b08d3622ad8b48 面向对象和反射相关的后面补充