pku 1548 Robots
This post is written in Chinese. Please consider using Google Translate
这是一个二维的LIS问题,先把第一维排序离散化,把第二维的值存到线性表A中。接下来就是求路径划分了,根据Dilworth定理,最长反链长度等于最小链划分数,所以只需求最长下降序列长度。
由于数值范围有限,可以用计数排序+基数排序,求LIS用二分查找,时间复杂度为O(NlogN)。
另外也可以直接用最小路径覆盖解决。
/*
* Problem: pku1548 Robots
* Author: Guo Jiabao
* Time: 2009.4.8 21:45
* State: Solved
* Memo: 二维LIS Dilworth定理 基数排序 二分查找
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
const int MAXN=601,INF=0x7FFFFFFF;
using namespace std;
struct point
{
int key[2];
}P[MAXN],Q[MAXN];
int N,Ans,A[MAXN],G[MAXN],C[25],order[MAXN];
void countingsort(int y)
{
int i;
memset(C,0,sizeof(C));
for (i=1;i<=N;i++)
C[P[i].key[y]]++;
for (i=1;i<=24;i++)
C[i]+=C[i-1];
for (i=N;i>=1;i--)
{
order[C[P[i].key[y]]]=i;
C[P[i].key[y]]--;
}
for (i=1;i<=N;i++)
Q[i]=P[order[i]];
for (i=1;i<=N;i++)
P[i]=Q[i];
}
void radixsort()
{
countingsort(1);
countingsort(0);
}
inline int binsearch(int v)
{
int a=0,b=N,m;
while (a+1<b)
{
m=(a+b)>>1;
if (G[m]<v)
a=m;
else
b=m-1;
}
if (G[b]<v)
a=b;
return a;
}
void dynamic()
{
int i,k;
radixsort();
A[0]=G[0]=0;
for (i=1;i<=N;i++)
{
A[N-i+1]=P[i].key[1];
G[i]=INF;
}
for (i=1;i<=N;i++)
{
k=binsearch(A[i]); //查找小于A[i]的最大G[k],返回k
if (A[i] < G[k+1])
G[k+1]=A[i];
}
for (i=N;i>=0;i--)
if (G[i]!=INF)
{
Ans=i;
break;
}
}
int main()
{
int x,y;
freopen("robots.in","r",stdin);
freopen("robots.out","w",stdout);
while (scanf("%d%d",&x,&y),x!=-1 || y!=-1)
{
N=Ans=0;
while (x!=0 || y!=0)
{
P[++N].key[0]=x;P[N].key[1]=y;
scanf("%d%d",&x,&y);
}
dynamic();
printf("%dn",Ans);
}
return 0;
}