zoukankan      html  css  js  c++  java
  • BZOJ4044: [Cerc2014] Virus synthesis(回文树+DP)

    Description

    Viruses are usually bad for your health. How about fighting them with... other viruses? In 
    this problem, you need to find out how to synthesize such good viruses. 
    We have prepared for you a set of strings of the letters A, G, T and C. They correspond to the 
    DNA nucleotide sequences of viruses that we want to svnthesize, using the following operations: 
    * Adding a nucleotide either to the beginning or the end of the existing sequence 
    * Replicating the sequence, reversing the copied piece, and gluing it either to the beginmng or 
    to the end of the original (so that e.g., AGTC can become AGTCCTGA or CTGAAGTC). 
    We're concerned about efficiency, since we have very many such sequences, some of them verv 
    long. Find a wav to svnthesize them in a mmimum number of operations. 
    你要用ATGC四个字母用两种操作拼出给定的串: 
    1.将其中一个字符放在已有串开头或者结尾 
    2.将已有串复制,然后reverse,再接在已有串的头部或者尾部 
    一开始已有串为空。求最少操作次数。 
    len<=100000 

    Input

    The first line of input contains the number of test cases T. The descriptions of the test cases 
    follow: 
    Each test case consists of a single line containing a non-empty string. The string uses only 
    the capital letters A, C, G and T and is not longer than 100 000 characters. 

    Output

    For each test case, output a single line containing the minimum total number of operations 
    necessary to construct the given sequence.

    Sample Input

    4
    AAAA
    AGCTTGCA
    AAGGGGAAGGGGAA
    AAACAGTCCTGACAAAAAAAAAAAAC

    Sample Output

    3
    8
    6
    18

     

    解题思路:

    有这样的性质:

    1.只能形成1个大回文串。

    2.只能生成偶回文串。 很有动归的思想嘛。 回文树上一个节点代表一个回文串,dp[i]表示在i节点的回文串最小生成代价:

    其中mid为长度小于len[i]/2的最长后缀回文串所在节点,可以倍增跳也可以从fa的mid开始跳。

    那么答案就是:

    就愉快地结束了。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 struct pant{
      5     int tranc[4];
      6     int len;
      7     int pre;
      8     int dp;
      9     int mid;
     10 }h[1000000],stpant;
     11 int a[100001];
     12 char tmp[100001];
     13 int siz;
     14 int fin;
     15 int len;
     16 int trans(char t)
     17 {
     18     if(t=='A')
     19         return 0;
     20     if(t=='G')
     21         return 1;
     22     if(t=='C')
     23         return 2;
     24     return 3;
     25 }
     26 void Res(void)
     27 {
     28     memset(a,0x3f,sizeof(a));
     29     a[0]=-1;
     30     h[1]=h[0]=stpant;
     31     h[1].pre=h[0].pre=1;
     32     h[1].len=-1;
     33     h[0].dp=1;
     34     siz=1;
     35     fin=0;
     36     return ;
     37 }
     38 bool mis(int i,int lsp)
     39 {
     40     return a[i]!=a[i-h[lsp].len-1];
     41 }
     42 void Insert(int i)
     43 {
     44     int nwp,lsp,mac;
     45     lsp=fin;
     46     int c=a[i];
     47     while(mis(i,lsp))
     48         lsp=h[lsp].pre;
     49     if(!h[lsp].tranc[c])
     50     {
     51         nwp=++siz;
     52         mac=h[lsp].pre;
     53         h[nwp]=stpant;
     54         h[nwp].len=h[nwp].dp=h[lsp].len+2;
     55         while(mis(i,mac))
     56             mac=h[mac].pre;
     57         h[nwp].pre=h[mac].tranc[c];
     58         h[lsp].tranc[c]=nwp;
     59         
     60         
     61         if(h[nwp].len<=2)
     62             h[nwp].mid=h[nwp].pre;
     63         else{
     64             mac=h[lsp].mid;
     65             while(mis(i,mac)||h[mac].len*2+4>h[nwp].len)
     66                 mac=h[mac].pre;
     67             h[nwp].mid=h[mac].tranc[c];
     68         }
     69         if(h[nwp].len%2==0)
     70         {
     71             h[nwp].dp=std::min(h[lsp].dp+1,h[nwp].len/2-h[h[nwp].mid].len+h[h[nwp].mid].dp+1);
     72         }
     73     }
     74     fin=h[lsp].tranc[c];
     75     return ;
     76 }
     77 int main()
     78 {
     79     int T=0;
     80     scanf("%d",&T);
     81     while(T--)
     82     {
     83         Res();
     84         scanf("%s",tmp+1);
     85         int ans;
     86         len=strlen(tmp+1);
     87         ans=len;
     88         for(int i=1;i<=len;i++)
     89             a[i]=trans(tmp[i]);
     90         for(int i=1;i<=len;i++)
     91             Insert(i);
     92         for(int i=2;i<=siz;i++)
     93         {
     94             if(h[i].len&1^1)
     95             {
     96                 ans=std::min(ans,len-h[i].len+h[i].dp);
     97                 
     98             }//printf("%d
    ",h[i].dp);
     99         }
    100         //return 0;
    101         printf("%d
    ",ans);
    102     }
    103     return 0;
    104 }
  • 相关阅读:
    selenium iframe 定位 qq空间说说
    单个 进程网速 消耗 网路 带宽
    网页加速
    baidu 验证网站 一一映射
    内容原发网站seo不重视2个标签,导致seo效果不如转发网站
    vi shell 的水平 决定了 手机shell 办公的效率
    键盘控制鼠标
    seo 谷歌去年悄然收购这家英国硬件公司
    视频 爬虫
    python 深浅 拷贝
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10085119.html
Copyright © 2011-2022 走看看