题解
这道题很像之前做过的导弹拦截的题目,关键点是偏序集。
显然答案就是这个二维数集合的最少链划分数,也就是最大的反链长度 (根据Dilworth定理)。
但是直接求反链还是难。
咱们先对其中一维由小到大排序,再对另外一维被固定的数,考察其非降序情况即可。
我看了一些贪心的做法也是可行的。
ps: 再次出现 bus error。 在sort()中必须要用严格升序,参见std::sort function gives “Bus error: 10”
Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int n,m;
struct point{
int l,w;
}cot[5002];
int f[5002];
typedef struct point P;
bool cmp(P &a, P &b){
return (a.l == b.l ? a.w<b.w : a.l<b.l);
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>cot[i].l>>cot[i].w;
}
sort(cot+1,cot+1+n,cmp);
int cur,ans=0;
for(int i=n;i>=1;i--){ // dp
cur = 0;
for(int j=i+1;j<=n;j++){
if( cot[i].w > cot[j].w )
cur = max(cur,f[j]);
}
f[i] = cur+1;
ans = max(ans,f[i]);
}
cout<<ans<<endl;
return 0;
}