zoj - 1076 - Gene Assembly
小心格式,又试了一次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; }