洛
谷
P
4873
[
U
S
A
C
O
14
D
E
C
]
C
o
w
J
o
g
G
o
l
d
牛
慢
跑
(
金
)
\color{#00F}{洛谷\ P4873\ [USACO14DEC] Cow Jog_Gold 牛慢跑(金)}
洛谷 P4873 [USACO14DEC]CowJogGold牛慢跑(金)
T
i
m
e
L
i
m
i
t
:
1000
M
S
\color{green}{Time Limit: 1000 MS}
TimeLimit:1000MS
M
e
m
o
r
y
L
i
m
i
t
:
125.00
M
B
\color{green}{Memory Limit: 125.00MB}
MemoryLimit:125.00MB
P
r
o
b
l
e
m
D
e
s
c
r
i
p
t
i
o
n
\color{blue}{Problem\ Description}
Problem Description
Farmer John 的
N
N
N 头奶牛
(
1
≤
N
≤
1
0
5
)
(1 ≤ N ≤ 10^5)
(1≤N≤105)正在一条长度无限的跑道上慢跑,每头奶牛都有一个不同的开始位置,以及不同的跑步速度。
为了方便奶牛们互相超越,整个跑道被分成了若干条赛道。在同一时刻,不可能有在同一条赛道上的两头奶牛占据相同的位置。
现在奶牛们要跑 T T T分钟,在跑步过程中,他们不会改变自己所在的赛道和自己跑步的速度。FJ想要知道,为了奶牛间不会发生冲突,他需要至少准备多少条赛道。
I
n
p
u
t
\color{blue}{Input}
Input
第一行包括两个整数
N
N
N 和
T
T
T 。接下来
N
N
N 行,每行两个整数
p
i
p_i
pi和
v
i
(
p
i
,
v
i
≤
1
0
9
)
v_i( p_i , v_i ≤ 10^9 )
vi(pi,vi≤109),分别代表奶牛的初始位置和速度。
O
u
t
p
u
t
\color{blue}{Output}
Output
一个整数,代表最少需要的跑道数目。
S
a
m
p
l
e
I
n
p
u
t
\color{blue}{Sample\ Input}
Sample Input
5 3
0 1
1 2
2 3
3 2
6 1
S
a
m
p
l
e
O
u
t
p
u
t
\color{blue}{Sample \ Output}
Sample Output
3
对于两头牛, A A A牛和 B B B牛,如果 A A A牛超过了 B B B牛,则说明 A A A牛初始位置 ⩽ B \ \leqslant B ⩽B牛初始位置且 A A A牛结束位置 ⩾ B \ \geqslant B ⩾B牛结束位置。在这种情况下,它们需要两条跑道。
同样的,如果有 k k k头牛,第一头牛超过第二头牛,第二头牛超过第三头牛……,则说明它们的初始位置是不下降的,结束位置是不上升的。在这种情况下,它们需要 k k k条跑道。
对于 n n n头牛,问它们最少需要多少跑道,其实就是能满足初始位置不下降,结束位置不上升最多能选出多少头牛。由于输入以按照升序,所以我们只要考虑结束位置就行。即求结束位置的最长不上升子序列。
代码实现如下:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=100000+10;
int n,t,top=0;
ll a[MAXN],q[MAXN];
inline ll read()
{
ll X=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+(ch^'0'); ch=getchar();}
return X*f;
}
int main()
{
//freopen("input.txt","r",stdin);
n=read(); t=read();
for(int i=1;i<=n;++i)
{
ll p=read(),v=read();
a[i]=(ll)p+v*t;
}
for(int i=n;i>=1;--i)//倒过来变成求最长不下降子序列
{
if(!top||a[i]>=q[top])
q[++top]=a[i];
else
{
ll pos=upper_bound(q+1,q+top+1,a[i])-q;
q[pos]=a[i];
}
}
printf("%lld",top);
return 0;
}