DNA repair :ac自动机 + DP

分析

f[I][j]表示第i位位于j位置的时候所对应的答案,然后枚举第i位的情况,判断会跳到哪里,如果该点打过标记,continue

代码


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
#define _CRT_SECURE_NO_WARNINGS
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){char c=getchar();T x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
int gcd(int a,int b){return (b>0)?gcd(b,a%b):a;}
int tr[N][4],idx;
int ne[N],cnt[N];
int f[1005][1005];
int q[N];
char str[N];
int n;

int get(char x){
    if(x == 'A') return 0;
    if(x == 'T') return 1;
    if(x == 'C') return 2;
    return 3;
}

void init(){
    memset(tr,0,sizeof tr);
    memset(f,0x3f,sizeof f);
    memset(cnt,0,sizeof cnt);
    memset(ne,0,sizeof ne);
    idx = 0;
}

void insert(){
    int p = 0;
    for(int i = 0;str[i];i++){
        int t = get(str[i]);
        if(!tr[p][t]) tr[p][t] = ++idx;
        p = tr[p][t];
    }
    cnt[p] = 1;
}

void build(){
    int hh = 0,tt = -1;
    for(int i = 0;i < 4;i++)
        if(tr[0][i])
            q[++tt] = tr[0][i];
    while(hh <= tt){
        int t = q[hh++];
        for(int i = 0;i < 4;i++){
            int c = tr[t][i];
            if(!c) tr[t][i] = tr[ne[t]][i];
            else{
                q[++tt] = c;
                ne[c] = tr[ne[t]][i];
                cnt[c] |= cnt[ne[c]];
            }
        }
    }
}

int main(){
    int T = 0;
    while(scanf("%d",&n) && n){
        printf("Case %d: ",++T);
        init();
        for(int i = 1;i <= n;i++){
            scanf("%s",str);
            insert();
        }
        build();
        f[0][0] = 0;
        scanf("%s",str + 1);
        n = strlen(str + 1);
        for(int i = 1;i <= n;i++)   
            for(int j = 0;j <= idx;j++)
                for(int k = 0;k < 4;k++){
                    int c = get(str[i]);
                    if(cnt[tr[j][k]]) continue;
                    f[i][tr[j][k]] = min(f[i][tr[j][k]],f[i - 1][j] + (c != k));
                }
        int ans = INF;
        for(int i = 0;i <= idx;i++) ans = min(ans,f[n][i]);
        if(ans == INF) ans = -1;
        di(ans);
    }
    
}

/**
*  ┏┓   ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃       ┃
* ┃   ━   ┃ ++ + + +
*  ████━████+
*  ◥██◤ ◥██◤ +
* ┃   ┻   ┃
* ┃       ┃ + +
* ┗━┓   ┏━┛
*   ┃   ┃ + + + +Code is far away from  
*   ┃   ┃ + bug with the animal protecting
*   ┃    ┗━━━┓ 神兽保佑,代码无bug 
*   ┃        ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/
上一篇:技术基础 | 舍弃”读修复概率”特性


下一篇:odoo开发:关于打印repair模块PDF报表,默认纸张头部有一大块空白无法修改的问题解决方案