第二发,走起
区间相交问题
[ 时间限制: 1 Sec 内存限制: 128 MB ]题目描述
给定x 轴上n (n<1000)个闭区间。去掉尽可能少的闭区间,使剩下的闭区间都不相交。
给定n 个闭区间,编程计算去掉的最少闭区间数。
输入
第一行是正整数n,表示闭区间数。接下来的n行中,
每行有2 个整数,分别表示闭区间的2个端点。输出
计算出去掉的最少闭区间数
样例输入
310 2010 1520 15
样例输出
2
思路
首先按右边端点双关键字排序,方便贪心,然后贪心接上a[i]的最大保留数,比较f[i]与f[j]+1,最后n-ans,得出最少去掉的区间.
代码
#include<bits/stdc++.h>
using namespace std;
struct sb
{
int l,r;
}a[50001];
bool cmp(sb x,sb y)//双关键字,按右端点升序排序
{
if(x.l!=y.l)
return x.l<y.l;
else
return x.r<y.r;
}
int f[100000],n,ans;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
if(a[i].l>a[i].r)swap(a[i].l,a[i].r);//防止开始时间在结束时间后
}
sort(a+1,a+n+1,cmp);//排序
f[1]=1;//第一个之前的保留的必定为1个
for(int i=2;i<=n;i++)
{
f[i]=1;//初始只有本身一个,保留的为1
for(int j=1;j<i;j++)//循环前面所有方案
{
if(a[i].l>a[j].r)//如果能接上,也就是a[i]的开头小于a[j]的结尾,就能接上
f[i]=max(f[i],f[j]+1);//比较长度,取最大值
}
ans=max(ans,f[i]);//最后再比较一次,因为最后一个不一定是多的(保留的越多,去掉的越少)
}
printf("%d",n-ans);//注意ans是保留数,不是去掉的
}