题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=76
先以起点为关键字从小到大排序,再求最长上升子序列(这里的上升是指右边的起点大于左边的终点)。
#include<iostream>
#include<memory.h>
#include<algorithm>
using namespace std;
struct node
{
int l,r;
int number;
};
node data[1100];
int father[1100];
int ans,pos;
void Find(int x, int deep)
{
if (father[x] != x)
Find(father[x],deep+1);
if (deep != 1)
cout<<data[x].number<<' ';
else
cout<<data[x].number<<endl;
}
int LIS(int n, node a[])
{
int b[1100];
int MAX = 0;
pos = 0;
for (int i=0; i<n; i++)
{
b[i] = 0;
for (int j=0; j<i; j++)
if (a[i].l > a[j].r && b[j] > b[i])
{
b[i] = b[j];
father[i] = j;
}
b[i]++;
if (b[i] > MAX)
{
MAX = b[i];
pos = i;
}
}
return MAX;
}
int cmp(node a, node b)
{
return (a.l < b.l || (a.l == b.l && a.r < b.r));
}
int main()
{
int n;
while (cin>>n && n)
{
for (int i=0; i<n; i++)
{
data[i].l = data[i].r = data[i].number = 0;
father[i] = i;
}
for (int i=0; i<n; i++)
{
cin>>data[i].l>>data[i].r;
data[i].number = i+1;
}
sort(data,data+n,cmp);
int ans = LIS(n,data);
Find(pos,1);
}
return 0;
}