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

    回文自动机上dp

    f[x]表示形成x代表的回文串所需的最小步数,

    若len[x]为奇数,f[x]=len[x],因为即使有更优的,也是直接添加,没有复制操作,那样就不用从x转移了。

    若len[x]为偶数,f[x]=min(f[fa[x]]+1,len[x]/2-len[fro[x]]+f[fro[x]]+1),因为fa[x]肯定是最后复制更优,那么将复制前的子串末尾加一个字符即可,fro则是len不大于len[x]/2的最长的x的fail.

    memsetT死了,改成每次只memset用的就过了

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define N 100050
     5 using namespace std;
     6 int len[N],ch[N][5],nxt[N],fro[N],f[N];
     7 int T,n,ans,last,tot;
     8 char s[N];
     9 inline void init(){
    10     ans=0x7fffffff;
    11     last=0;tot=1;
    12     memset(ch[0],0,sizeof ch[0]);
    13     memset(ch[1],0,sizeof ch[1]);
    14     nxt[0]=nxt[1]=1;
    15     len[1]=-1;
    16 }
    17 inline int getfail(int x,int en){
    18     while(s[en]!=s[en-len[x]-1])x=nxt[x];
    19     return x;
    20 }
    21 inline void insert(int t,int en){
    22     int now=getfail(last,en);
    23     if(!ch[now][t]){
    24         int x=++tot;
    25         memset(ch[x],0,sizeof ch[x]);
    26         len[x]=len[now]+2;
    27         int fa=getfail(nxt[now],en);
    28         nxt[x]=ch[fa][t];
    29         fa=fro[now];
    30         if(len[x]<=2)fro[x]=0;
    31         else{
    32             while(s[en]!=s[en-len[fa]-1]||(len[fa]+2)*2>len[x])
    33                 fa=nxt[fa];
    34             fro[x]=ch[fa][t];
    35         }
    36         if(len[x]&1||len[x]<=2)f[x]=len[x];
    37         else f[x]=min(f[now]+1,len[x]/2-len[fro[x]]+f[fro[x]]+1);
    38         ans=min(ans,n-len[x]+f[x]);
    39         ch[now][t]=x;
    40     }
    41     last=ch[now][t];
    42 }
    43 int hash(char x){
    44     if(x=='A')return 0;
    45     if(x=='T')return 1;
    46     if(x=='C')return 2;
    47     return 3;
    48 }
    49 void work(){
    50     init();
    51     scanf("%s",s);
    52     n=strlen(s);
    53     for(int i=0;i<n;i++)
    54         insert(hash(s[i]),i);
    55     printf("%d
    ",ans);
    56 }
    57 int main(){
    58     scanf("%d",&T);
    59     while(T--)work();
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    数字雨-贪吃蛇
    C语言入门9-2-模块大致一览
    C语言入门9-1-分类函数
    C语言入门8-数组-基本算法
    C语言入门7-程序设计方法基础-循环结构
    C语言入门6-选择结构--f语句-switch
    C语言入门5-键盘的输入和屏幕输出
    C语言入门4-运算符和表达式
    C语言入门3-C语言概述及数据类型
    Systemd 入门教程:命令篇
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8184403.html
Copyright © 2011-2022 走看看