ZOJ 1076 Gene Assembly(LIS+路径打印 贪心)
2013-08-03 15:38
399 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=76
题目大意:在一个DNA上,给定许多基因的起始位置和结束位置,求出这条链上最多同时存在多少基因?并依次输出选择基因的序列号。
Sample Input
6
340 500
220 470
100 300
880 943
525 556
612 776
3
705 773
124 337
453 665
0
Sample Output
3 1 5 6 4
2 3 1
分析:有两种思路。1.最长上升子序列+路径打印;2.贪心
法1:
法2:
题目大意:在一个DNA上,给定许多基因的起始位置和结束位置,求出这条链上最多同时存在多少基因?并依次输出选择基因的序列号。
Sample Input
6
340 500
220 470
100 300
880 943
525 556
612 776
3
705 773
124 337
453 665
0
Sample Output
3 1 5 6 4
2 3 1
分析:有两种思路。1.最长上升子序列+路径打印;2.贪心
法1:
//dp[i] = max{0,dp[j]}+1,j<i //时间复杂度仍为 O(n^2) // # include<stdio.h> # include<string.h> # include<stdlib.h> # define MAX 1001 struct node{ int x,y,id; //x,y分别是基因起始和结束位置,id表示基因的序列号 }data[MAX]; int n; int pre[MAX]; //记录前驱 int dp[MAX]; //LIS中保存最大数目 int output[MAX]; //记录输出 int cmp(const void *a,const void *b){ //将序列从小到大排序 struct node *c = (node *)a; struct node *d = (node *)b; if(c->x == d->x) return c->y - d->y; return c->x - d->x; } void solve(){ int i,j,m; qsort(data,n,sizeof(data[0]),cmp); pre[0] = -1; dp[0] =1; for(i=1;i<n;i++){ pre[i] = -1; dp[i] = 1; m = 0; for(j=0;j<i;j++){ if(data[j].y < data[i].x){ if(m<dp[j]){ m = dp[j]; //LIS pre[i] = j; } } } dp[i] += m ; } j = m = 0; for(i=0;i<n;i++){ //找到最长的序列的最后一个 if(dp[i] > m){ j = i; m = dp[i]; } } i = 0; while(j != -1){ output[i++] = j; j = pre[j]; } for(j=i-1; j>0; j--) printf("%d ",data[output[j]].id); printf("%d\n",data[output[j]].id); } int main(){ while(scanf("%d",&n) && n){ for(int i=0;i<n;i++){ scanf("%d%d",&data[i].x,&data[i].y); data[i].id = i+1; } solve(); } return 0; }
法2:
/*可以将基因起始点看成一个作业的开始时间,基因终点看成完成该作业的终止时间。用这些基因拼出长度最长的基因序列(连续的基因前一个终点不能大于等于后一个基因起始点),相当于求能完成的最多作业序列。这是贪心的典型例题。可用贪心算法解决,贪心策略——优先考虑先完成的作业。*/ #include <stdio.h> #include <string.h> int input[1001][3]; //input[i][0]:起始位置,input[i][1]:终止位置,input[i][2]:编号 int main( ) { int N, i, j, k; int temp, max; /*输入基因个数N,N=0时测试结束*/ while( scanf( "%d", &N ) ) { if( N==0 ) break; //输入结束 memset( input, 0, sizeof(input) ); /*输入基因起始点,终止点,并给基因编号*/ for( i=0; i<N; i++ ) { scanf( "%d%d", &input[i][0], &input[i][1] ); input[i][2] = i + 1; } /*对基因按终止点小的排序,<1000的用例,选择排序法*/ for( i=0; i<N; i++ ) { temp = input[i][1]; k = i; for( j = i + 1; j<N; j++ ) { if( temp>input[j][1] ) { k = j; temp = input[j][1]; } } temp = input[i][0]; input[i][0] = input[k][0]; input[k][0] = temp; temp = input[i][1]; input[i][1] = input[k][1]; input[k][1] = temp; temp = input[i][2]; input[i][2] = input[k][2]; input[k][2] = temp; } /*贪心选择输出被选择的基因编号*/ max = input[0][1]; printf( "%d", input[0][2] ); for( i=1; i<N; i++ ) { if( input[i][0]>max ) { printf( " %d", input[i][2] ); max = input[i][1]; } } printf("\n"); } return 0; }
相关文章推荐
- ZOJ1076-Gene Assembly(贪心)
- ZOJ 1076 Gene Assembly(LIS)
- ZOJ 1076 Gene Assembly (贪心求区间不相交问题)
- uva481(打印LIS路径)
- 贪心,Gene Assembly,ZOJ(1076)
- LIS之贪心加二分,,求最大长---记录路径(待检验--欢迎提供数据)
- ZOJ 1076 Gene Assembly 贪心
- zoj1076-Gene Assembly
- LIS最长上升子序列(打印路径)
- uva 10131 Is Bigger Smarter?(动态规划:LIS变形+路径打印)
- zoj 1076 Gene Assembly 贪心
- Uva 10131 Is Bigger Smarter? (LIS,打印路径)
- zoj 1076 Gene Assembly
- [贪心]ZOJ1012、1076
- hdu--1160--LIS+打印路径
- Uva 10131 Is Bigger Smarter? (LIS,打印路径)
- ZOJ 2319 Beautiful People(LIS二分法+路径输出)
- UVa 103 - Stacking Boxes (LIS,打印路径)
- ZOJ 1076 Gene Assembly LIS
- 2015 UESTC Training for Dynamic Programming N - 导弹拦截 LIS nlog(n)+打印字典序最小的路径