题目链接: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; }