链接
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1025
题意
给你 n n n个 ( l , w ) (l,w) (l,w),你排列它们,你尽可能地想使得 l i − 1 < = l i a n d w i − 1 < = w i l_{i-1}<=l_i\ and\ w_{i-1}<=w_i li−1<=li and wi−1<=wi,问你最少有多少个子序列,序列中的任意连续两个区间都满足上述条件,输出满足的个数;
题解
对 l l l排序对 w w w贪心或对 w w w排序对 l l l贪心,对于一个以 l l l升序排列好的区间集合,对于第一个 w w w,去找大于等于它的下一个 w 1 w1 w1,在以这个 w 1 w1 w1为基准找下一个大于等于它的 w 2 w2 w2…最后就找到了一个子序列,然后从开头找第二个子序列,中间需要定义一个数组 v i s vis vis用来标记,表示选过它,下次就不选它了;
代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>
using namespace std;
#define inf 0x7f7f7f7f
#define maxn 51000
#define mod 1000000007
#define N 1
#define P 2
typedef long long ll;
int t,n,vis[5005];
typedef struct{
int l,w;
}node;
node p[5005];
bool com(node a,node b){
if(a.l==b.l)return a.w<b.w;
return a.l<b.l;
}
int main(){
cin>>t;
while(t--){
cin>>n;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
cin>>p[i].l>>p[i].w;
sort(p+1,p+1+n,com);
int res=0;
for(int i=1;i<=n;i++){
if(!vis[i]){
res++;
vis[i]=1;
int k=i;
for(int j=i+1;j<=n;j++){
if(!vis[j]&&p[j].w>=p[k].w){
vis[j]=1;
k=j;
}
}
}
}
cout<<res<<endl;
}
}