描述: n段线段,求最长的序列,使得后一条线段包含前一条线段。
拓扑排序,然后dp。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<queue>
#include<map>
using namespace std;
#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define DOR(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define bug puts("Fuck");
#define LL long long
#define pb push_back
#define mp make_pair
#define nMax 510
#define eps 1e-8
#define inf 0x7fffffff
struct Seg{
int x,y;
void read(){ scanf("%d%d",&x,&y);}
friend bool operator < (Seg& a, Seg& b) {
return b.x<a.x && b.y>a.y;
}
} s[nMax];
int in[nMax],first[nMax],to[nMax*nMax],nxt[nMax*nMax],e;
void init(int n){
FOR(i,1,n) first[i]=-1,in[i]=0;
e = 0;
}
void addedge(int u,int v){
to[e]=v;nxt[e]=first[u];first[u]=e;e++;
}
int n,ts[nMax];
void Topsort(){
int k = 1;
while(1){
int ok = 0;
FOR(i,1,n)if(in[i] == 0) {
//printf("******* %d\n",i);
ts[k++]=i;
for(int j=first[i];j!=-1;j=nxt[j]) in[to[j]] --;
in[i]=-1;
ok = 1;
}
if(!ok) break;
}
}
int dp[nMax],fa[nMax];
int DP(){
FOR(i,1,n) dp[i]=fa[i]=0;
int ans,sum=0;
FOR(u,1,n) {
dp[u]=1;fa[u]=u;
FOR(v,1,u-1) if(s[ts[v]] < s[ts[u]] && dp[v]+1 > dp[u]) {
dp[u]=dp[v]+1;
fa[u]=v;
}
if(sum < dp[u]) {
sum = dp[u];
ans = u;
}
}
return ans;
}
void out(int u){
if(u==fa[u]){
printf("%d",ts[u]);
return ;
}
out(fa[u]);
printf(" %d",ts[u]);
}
void sovle(){
init(n);
FOR(i,1,n) FOR(j,1,n) if(s[i]<s[j]) {
addedge(i,j);in[j]++;
}
Topsort();
//FOR(i,1,n) printf("%d : %d %d\n",ts[i],s[ts[i]].x,s[ts[i]].y);
int ans;
printf("%d\n",dp[ans=DP()]);
out(ans);printf("\n");
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
while(~scanf("%d",&n)){
FOR(i,1,n)s[i].read();
sovle();
}
return 0;
}