zoukankan      html  css  js  c++  java
  • USACO 2014 December Contest Gold T3: Cow Jog

    题目大意

    Farmer John 的 N 头奶牛 ( 1 ≤ N ≤ 1e5 ) 正在一条长度无限的跑道上慢跑,每头奶牛都有一个不同的开始位置,以及不同的跑步速度。

    为了方便奶牛们互相超越,整个跑道被分成了若干条赛道。在同一时刻,不可能有在同一条赛道上的两头奶牛占据相同的位置。

    现在奶牛们要跑 T 分钟,在跑步过程中,他们不会改变自己所在的赛道和自己跑步的速度。FJ想要知道,为了奶牛间不会发生冲突,他需要至少准备多少条赛道。

    输入格式:第一行包括两个整数 N 和 T 。接下来 N 行,每行两个整数 pi 和 vi ( pi,vi ≤ 1e9 )分别代表奶牛的初始位置和速度。

    输出格式:一个整数,代表最少需要的跑道数目。

    题目分析

    考虑什么情况下两头奶牛 i , j 不能同时处在一条赛道上。

    假设 i 的起始位置比 j 小,那么当 i 的结束位置>= j 的结束位置时,i 和 j 就不能同时处在一条跑道上了。

    因为牛的起始位置 Si 读入时是从小到大的,所以假设读入到 i 牛, 我们可以算出它的结束位置 Ti,

    若之前的某头牛 j (之前的牛起点都比 Si 小)的结束位置 Tj 比 Ti 要小,那么就说明牛 i 和 牛 j 可以处在同一条跑道上。

    贪心地想,我们要让 Ti 与 Tj 的距离差尽量小,这样才能保证跑道被“充分利用”。

    所以,每读入一头牛 i ,我们就把它的结束位置 Ti 与前面的牛比较,找到一个最大的比 Ti 小的 Tj,把 Ti 接到 Tj 后面;若找不到,就把他存下来。

    最后存下来的个数即需要跑道的最小个数。

    哎?这不就是最长不下降子序列(LIS)吗?所以直接用 数组+二分查找 在O(N logN)时间内实现即可。

    (USACO上求LIS的方法很简短,值得学习。)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4  
     5 int n;
     6 ll t;
     7 vector<ll> a;
     8 int main(){
     9     scanf("%d%lld",&n,&t);
    10     for(int i=1;i<=n;++i){
    11         ll pos,v;
    12         scanf("%lld%lld",&pos,&v);
    13         pos=-(pos+v*t);
    14         if(a.empty()||pos>=a.back())
    15             a.push_back(pos);
    16         else
    17             *upper_bound(a.begin(),a.end(),pos)=pos;
    18         //for(int j=0;j<(int)a.size();++j)
    19         //    cout<<a[j]<<' ';
    20         //cout<<endl;
    21     }
    22     printf("%d
    ",(int)a.size());
    23     return 0;
    24 }
  • 相关阅读:
    读书笔记:A Philosophy of Software Design
    面向对象编程—价值万亿美元的灾难
    刚哥谈架构 (二) 我眼中的架构师
    软件质量成本神话
    API 如何选择 REST,GraphQL还是gRPC
    影响您的代码库的10个编程代码味道
    为什么要不断重构
    php导出excel表格的使用
    浅谈HTTP中Get与Post的区别
    C# 程序配置文件的操作(ConfigurationManager的使用)
  • 原文地址:https://www.cnblogs.com/LI-dox/p/11212720.html
Copyright © 2011-2022 走看看