小心格式,又试了一次PE!!!
#include <iostream>
#include <string.h>
using namespace std;
const int maxn = 1000 + 10;
int a[maxn], b[maxn], d[maxn], G[maxn][maxn]; //a为外显子的起始点,b为外显子的终止点,d为路径长度,G为图
int n, first; //n为外显子的个数,first在输出时做标记(按格式输出的方法之一)
int dp(int i) //核心代码,图记忆化搜索
{
int& ans = d[i]; //ans用来做d的别名,尽显方便
if(ans > 0) return ans; //真正的返回在这里,返回的是最长路径
ans = 1; //已到达点i,记路径长度为1,注意:对ans的赋值即为对d[i]的赋值
int j;
for(j = 1; j <= n; j++) //是否可以从i到j
if(G[i][j])
ans = (ans > dp(j)+1 ? ans : dp(j)+1); //因为可能不止1个j符合条件,所以这里需要判断,力求最大的那个j
return ans;
}
void print(int i) //递归输出路径函数
{
int j;
if(first) first = !first; //小心不要在末尾多加一个空格,否则PE
else cout<<" ";
cout<<i;
for(j = 1; j <= n; j++)
if(G[i][j] && d[i] == d[j]+1)
{
print(j);
break; //输出任意的一条路径就可以了,故用break
}
}
int main()
{
while(cin>>n)
{
if(n == 0) return 0;
int i, j;
for(i = 1; i <= n; i++)
cin>>a[i]>>b[i];
memset(G, 0, sizeof(G));
memset(d, 0, sizeof(d));
for(i = 1; i <= n; i++) //建图
for(j = 1; j <= n; j++)
if(b[i]<a[j]) G[i][j] = 1;
int sum = 0, best; //寻找最长路径从哪个外显子开始
for(i = 1; i <= n; i++)
if(dp(i) > sum)
{
best = i;
sum = dp(i);
}
first = 1;
print(best);
cout<<endl;
}
return 0;
}