zoukankan      html  css  js  c++  java
  • Bzoj4044 [Cerc2014] Virus synthesis

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 215  Solved: 83

    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

    HINT

     

    Source

    字符串 回文自动机 DP

    手推一波可以发现,一个串是由它所包含的某个回文串加上其他的零散字符拼成的。

    设g[S]为拼成字符串S的最小步数,有:g[S]=min{g[C]+len[S]-len[C]} (C是被S包含的一个回文串)

    找回文串的过程可以用回文自动机完成,建回文自动机的时候,DP也可以顺便做完。

    无脑初始化被常数卡飞,用某个点时才初始化它就过了

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 using namespace std;
     7 const int mxn=200010;
     8 int a[150];
     9 int T,ans,tot;
    10 char s[mxn];
    11 struct HWM{
    12     int t[mxn][5];
    13     int fa[mxn],hf[mxn],S,last,cnt;
    14     int len[mxn];
    15     int g[mxn];
    16     void clear(int x){memset(t[x],0,sizeof t[x]);}
    17     void init(){
    18         S=last=cnt=1;
    19         fa[0]=fa[1]=1;
    20         hf[0]=hf[1]=1;
    21         clear(0);clear(1);
    22         g[0]=1;
    23         len[0]=0;len[1]=-1;
    24         return;
    25     }
    26     void insert(int c,int n){
    27         int p=last;
    28         while(s[n-len[p]-1]!=s[n])p=fa[p];
    29         if(!t[p][c]){
    30             int np=++cnt;
    31             t[p][c]=np;
    32             clear(np);
    33             len[np]=len[p]+2;
    34             if(p==1){
    35                 fa[np]=hf[np]=0;
    36             }
    37             else{
    38                 int k=fa[p];
    39                 while(s[n-len[k]-1]!=s[n])k=fa[k];
    40                 fa[np]=t[k][c];
    41                 k=hf[p];
    42                 while(s[n-len[k]-1]!=s[n] || (len[np]<((len[k]+2)<<1)) ){
    43                     k=fa[k];
    44                 }
    45                 hf[np]=t[k][c];
    46             }
    47             if(len[np]&1){
    48                 g[np]=min(len[np],g[hf[np]]+(len[np]-len[hf[np]]));
    49             }
    50             else{
    51                 g[np]=min(g[p]+1,g[hf[np]]+(len[np]>>1)-len[hf[np]]+1);
    52             }
    53             ans=min(ans,tot-len[np]+g[np]);
    54 //            printf("len:%d g:%d hf_len:%d ans:%d sz:%d
    ",len[np],g[np],g[hf[np]],ans,tot);
    55         }
    56         last=t[p][c];
    57         return;
    58     }
    59 }hm;
    60 int main(){
    61     int i,j;
    62     a['A']=1;a['G']=2;a['C']=3;a['T']=4;
    63     scanf("%d",&T);
    64     while(T--){
    65         scanf("%s",s+1);
    66         hm.init();
    67         int n=strlen(s+1);tot=n;
    68         ans=n;
    69         for(i=1;i<=n;i++)
    70             hm.insert(a[s[i]],i);
    71         printf("%d
    ",ans);
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    常量的三种定义方式和static在c语言中的三种修饰
    字符串的定义方式;输出和计算长度时的细节
    指针小白:修改*p与p会对相应的地址的变量产生什么影响?各个变量指针的长度为多少?
    习题 :任意输入十个数按大小排序;构造简单数学运算模块(形参和实参)
    for循环简单实例(打印乘法表,打印菱形)
    几个简单if程序的细节比较与加法程序设计
    冒泡排序法,两个数组内容的互换,两个变量之间的交换
    scanf加不加 ?
    jqplot导入包小结
    使用ajax与jqplot的小体会
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6862573.html
Copyright © 2011-2022 走看看