P4873 [USACO14DEC] Cow Jog_Gold 牛慢跑(乱搞?二分?)

(话说最近写的这类题不少啊。。。)

 

化简:给定数轴上一系列点,向正方向移动,点不能撞在一起,如果碰到一起就需要放到另外一行,求要多少行才能满足所有点不相撞的条件。

(被标签误解,老是想到二分答案。。。)

这题其实不难。首先,答案一定是最大相撞的那个点。(开的道可以共用)

然后,这题就比较明朗了。要找的就是一个点,它后面的点在t时刻堆在它头上最多。

也就是到终点的距离超过了它。

这个关系有点眼熟.....有点像逆序对啊。。。或者说,对一个点求逆序对...亦或者...最长不(上升下降不管了)子序列(对结束点求)?

那....有请我们的lower_bound上场。(每个点*-1,才能求小于等于它的最大值)

但是,发现不对....wa了不少点。

回头想想,大思路应该没有问题,一定是哪个细节的问题。

翻了翻边界,发现是最长不上升子序列,所以lower_bound的一个等号是罪魁祸首...

于是改成upper_bound就行了啊。。。

 于是不断(贪心地)更新,就能找到答案了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e6+10;
struct node
{
    ll x,v,st,ed;
}a[maxn];

ll q[maxn];
ll n,t;
ll tot;
int main()
{
    scanf("%lld%lld",&n,&t);
    for(int i=1;i<=n;i++)
    {
        ll x,y;
        scanf("%lld%lld",&x,&y);
        a[i].st=x;
        a[i].ed=x+y*t;
    }
    q[++tot]=-a[1].ed;
    for(int i=2;i<=n;i++)
    {
        ll x=-a[i].ed;
        if(x>=q[tot])
        {
            q[++tot]=x;
        }
        else
        {
            int k=upper_bound(q+1,q+tot+1,x)-q;
            q[k]=x;
        }
    }
    printf("%lld",tot);    
    return 0;
}

(完)

posted @ 2019-11-01 00:27  阿基米德的澡盆  阅读(125)  评论(0编辑  收藏  举报