poj 1548 Dilworth定理(机器人清理垃圾)

题意:一个矩形区域,在若干个给定的坐标上有垃圾。机器人从西北角(矩形区域的左上角)开始清理,它只能向东或者向南行进,如果到达了东南角(矩形区域的右下角)则完成了它的使命。问最少用多少个机器人可以将所有的垃圾清理完毕。

思路:Dilworth定理应用。把坐标看成一对数组,也就是求这个数组的最长反链。实际上这样一看,与poj1065的题意如出一辙。先排序,然后求最长下降子序列。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 28
typedef struct node{
    int a,b;
}node;
node p[N*N];
int dp[N],n=0,len=0,a,b;
int cmp(const void *a,const void *b){
    if((*(node *)a).a == (*(node *)b).a)
        return (*(node *)a).b - (*(node *)b).b;
    return (*(node *)a).a - (*(node *)b).a;
}
int find (int x,int len){
    int low,high,mid;
    low = 0;
    high = len;
    while(low <= high){
        mid = (low+high)>>1;
        if(dp[mid] == x)
            return mid;
        else if(dp[mid] > x)
            low = mid+1;
        else
            high = mid-1;
    }
    return low;
}
int main(){
    while(scanf("%d %d",&a,&b) &&a!=-1&&b!=-1){
        int i,j;
        if(a && b){
            p[n].a = a;
            p[n++].b = b;
            continue;
        }
        qsort(p,n,sizeof(node),cmp);
        for(i = 0;i<n;i++){
            j = find(p[i].b,len);
            if(j == len+1)
                dp[++len] = p[i].b;
            else
                dp[j] = p[i].b;
        }
        printf("%d\n",len+1);
        n = 0;
        len = 0;
        memset(dp,0,sizeof(dp));
    }
    return 0;
}



你可能感兴趣的:(poj 1548 Dilworth定理(机器人清理垃圾))