ZOJ 1076 Gene Assembly LIS
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=76
题目大意:
题目前面都是废话。
给你一串基因,然后给你上面的外显子的起始和终止位置,求最长上升子序列(LIS)
并且输出这些外显子的序号
思路:
直接DP,DP更新的时候用一个数组记录当前结点上一个是什么。最后用类似并查集的方法找到最开始的那一个。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=50000+10; struct exons { int begin,end; int id; }a[MAXN]; bool operator < (const exons &x,const exons &y) { return x.begin < y.begin || x.begin==y.begin && x.end < y.end; } int dp[MAXN]; int pre[MAXN]; int ans[MAXN]; int main() { int n; while(~scanf("%d",&n),n) { for(int i=0;i<n;i++) { scanf("%d%d",&a[i].begin,&a[i].end); a[i].id=i+1; } sort(a,a+n); memset(dp,0,sizeof(dp)); memset(pre,-1,sizeof(pre)); dp[0]=1; for(int i=1;i<n;i++) { for(int j=0;j<=i;j++) { if(a[i].begin >= a[j].end && dp[i] < dp[j]+1) { dp[i]=dp[j]+1; pre[i]=j; } } } int len=0; for(int i=n-1;i!=-1;i=pre[i]) { ans[len++]=a[i].id; } for(int i=len-1;i>0;i--) printf("%d ",ans[i]); printf("%d\n",ans[0]); //printf("%d\n",dp[n-1]); } return 0; }
新 blog : www.hrwhisper.me