您的位置:首页 > 其它

ZOJ 1076 Gene Assembly (贪心求区间不相交问题)

2015-03-22 21:17 417 查看

Statement of the Problem
With the large amount of genomic DNA sequence data being made available, it is becoming more important to find genes (parts of the genomic DNA which are responsible for the synthesis of proteins) in these sequences. It is known that for eukaryotes (in contrast
to prokaryotes) the process is more complicated, because of the presence of junk DNA that interrupts the coding region of genes in the genomic sequence. That is, a gene is composed by several pieces (called exons) of coding regions. It is known that the order
of the exons is maintained in the protein synthesis process, but the number of exons and their lengths can be arbitrary.

Most gene finding algorithms have two steps: in the first they search for possible exons; in the second they try to assemble a largest possible gene, by finding a chain with the largest possible number of exons. This chain must obey the order in which the
exons appear in the genomic sequence. We say that exon i appears before exon j if the end of i precedes the beginning of j.

The objective of this problem is, given a set of possible exons, to find the chain with the largest possible number of exons that cound be assembled to generate a gene.

Input Format

Several input instances are given. Each instance begins with the number 0 < n < 1000 of possible exons in the sequence. Then, each of the next n lines contains a pair of integer numbers that represent the position in which the exon starts and ends in the
genomic sequence. You can suppose that the genomic sequence has at most 50000 basis. The input ends with a line with a single 0.

Output Format

For each input instance your program should print in one line the chain with the largest possible number of exons, by enumerating the exons in the chain. If there is more than one chain with the same number of exons, your program can print anyone of them.

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

题目大意:给定一条数轴上的一些区间的起点和终点,求这条数轴上最多有多少个区间不相交,并按从左到右的位置输出他们的序号。

一个典型的贪心法求区间不相交问题,大致思路是:如果一个区间结束的位置最早,那么我一定会选择这个区间,因为它对后面的选择影响最小,换句话说后面就可以塞进更多的区间。同理,那么这个区间结束以后,我会去选择结束位置第二早的区间,但前提是这个区间的开始位置晚于上一个区间的结束位置,如果不符合这个条件的话,我一定会去选择结束位置第三晚的区间。。。。。。。以此类推,做出题目。

代码的话,首先对所有区间的结束位置升序排列(对开始位置降序排列也可以,不过那样就和上面的过程恰好相反)然后从第一个区间开始,逐一按上面所说的方法进行判断和选点。

建议使用结构体实现,并注意排序函数中cmp的写法。

代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>

using namespace std;

struct gen
{
int begin0;
int end0;
int num;
}a[1002];

bool cmp(gen x0,gen y0)
{
return (x0.end0<=y0.end0);
}

int main()
{
int i,n,j,k=1,flag,ans[1002];
do
{
scanf("%d",&n);
if (n==0)
{
break;
}
k=1;
memset(ans,0,sizeof(ans));
for (i=0;i<=n-1;i++)
{
scanf("%d%d",&a[i].begin0,&a[i].end0);
a[i].num=i+1;
}
sort(a,a+n,cmp);
j=0;
ans[0]=a[0].num;
do
{
i=j;
flag=0;
for(j=i+1;j<=n-1;j++)
{
if (a[i].end0<=a[j].begin0)
{
ans[k]=a[j].num;
k++;
flag=1;
break;
}
}
if (flag==0)
{
break;
}
}while(1);
for (i=0;i<=k-2;i++)
{
printf("%d ",ans[i]);
}
printf("%d",ans[k-1]);
printf("\n");
}while(1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  zoj 贪心