xmu 1041 Sequence导弹拦截问题的变形—贪心解

1041: Sequence

Description

  Giving a collection S of points on two dimension plane. (S = {(x0,y0), (x1,y1), ... }) We define a point is greater than another point when all its coordinate on two axis are both greater than or equel to another one. Namely, p is greater than q when xp >= xq and yp >= yq. A sequence is a list points < p1, p2, ... > satisfy that i < j => pi is greater than pj. You can use the elements in S to construct sequences, how many sequences needed to cover a S at least?

Input

  The input consists of several test cases. Each test case start with a line containing a number n(0 < n <= 1000000), the number of points in S. Then n lines follows, each line containing two number, xi, yi(0 <= xi, yi < 100000), the position of point i. The input end with EOF.

Output

  You have to print minium number of sequences needed to cover S in a single line for each case.

Sample Input

4
1 1
2 2
3 3
4 4

4
1 5
2 6
2 3
3 4

Sample Output

1
2

HINT

Source



等效题意:给定一些点,然后按要求分类(有顺序要求),问至少可以分成多少类。虽然这也被归类于动态规划,但我觉得归类为贪心还好一点。
思路:就是一个导弹拦截问题的变形,对坐标排一下序就行了。我们先对x从大到小排序,相同则按y大到小排序,然后逐个判断每个点,利用贪心,每次替换掉离他最近的那个点:由于x方向上已经有序,那么我们只需要在y方向上找到不小于他的点,然后替换掉即可,没找到,则答案加1.

代码:
#include<bits/stdc++.h>
#define maxn 1000010

using namespace std;
struct node{
    int x,y;
    bool operator <(const node&a)const{
        if(x!=a.x) return x<a.x;
        return y<a.y;
    }
}A[maxn];

int N;
set<int> st;set<int>::iterator it;

int judge(int k){
    it=st.lower_bound(A[k].y);//利用set的自排序和“二分”查找可以方便很多
    if(it!=st.end()){
        st.erase(*it);st.insert(A[k].y);
        return 1;
    }
    st.insert(A[k].y);return 0;
}


int main(){
    //freopen("in.txt","r",stdin);
    while(cin>>N){
        for(int i=0;i<N;i++)
            scanf("%d %d",&A[i].x,&A[i].y);
        sort(A,A+N);
        int cnt=0;
        st.clear();
        for(int i=N-1;i>=0;i--)
            if(judge(i)) continue;
            else cnt++;
        printf("%d\n",cnt);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值