zoukankan      html  css  js  c++  java
  • ZOJ 1076 排序+动态规划

    Gene Assembly

    Time Limit: 2 Seconds      Memory Limit: 65536 KB

    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

    解题思路:

       首先对所给的组排个序(第一个数先,如果第一个数相等,再看第二个数),再进行一个类似于最长上升子序列的排序;

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<vector>
     6 #include<cstdlib>
     7 #include<stack>
     8 #include<math.h>
     9 using namespace std;
    10 const int maxn=1007;
    11 int dp[maxn];
    12 int road[maxn];
    13 int n;
    14 struct node
    15 {
    16     int a,b,id;
    17 };
    18 node num[maxn];
    19 bool cmp(node n1,node n2)
    20 {
    21     if(n1.a<n2.a) return 1;
    22     return n1.b<n2.b;
    23 }
    24 int slove()
    25 {
    26     memset(dp,0,sizeof(dp));
    27     memset(road,-1,sizeof(road));
    28     for(int i=1;i<=n;i++)
    29     {
    30         for(int j=0;j<i;j++)
    31             if(num[j].b<=num[i].a)
    32             {
    33                 if(dp[j]+1>dp[i]){
    34                     dp[i]=dp[j]+1;
    35                     road[i]=j;
    36                 }
    37             }
    38     }
    39     int ans=1;
    40     for(int i=1;i<=n;i++)
    41     {
    42         if(dp[i]>dp[ans]){
    43             ans=i;
    44         }
    45     }
    46     return ans;
    47 }
    48 int main()
    49 {
    50     while(~scanf("%d",&n)){
    51             if(n==0) break;
    52         for(int i=1;i<=n;i++)
    53         {
    54             scanf("%d%d",&num[i].a,&num[i].b);
    55             num[i].id=i;
    56         }
    57         sort(num+1,num+n+1,cmp);
    58         int ans=slove();
    59         stack<int> s;
    60         while(!s.empty()) s.pop();
    61         int k=ans;
    62         while(k!=0){
    63             s.push(num[k].id);
    64             k=road[k];
    65         }
    66         bool first=1;
    67         while(!s.empty()){
    68             if(first){
    69                 printf("%d",s.top());
    70                 s.pop();
    71                 first=0;
    72             }
    73             else {printf(" %d",s.top());
    74             s.pop();}
    75         }
    76         printf("
    ");
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    匈牙利算法——S.B.S.
    洛谷P1328 生活大爆炸版石头剪刀布——S.B.S.
    洛谷P1101 单词方阵——S.B.S.
    noip2010提高组3题题解 by rLq
    洛谷P1605 迷宫——S.B.S.
    yii2.0 curd操作
    我常用的linux命令
    常用css
    ln 软链
    crontab下git命令无效
  • 原文地址:https://www.cnblogs.com/codeyuan/p/4358107.html
Copyright © 2011-2022 走看看