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