zoukankan      html  css  js  c++  java
  • BZOJ 4032: [HEOI2015]最短不公共子串 (dp*3 + SAM)

    转博客大法好

    第4个子任务中,为什么只转移最近的一个位置,自己YY吧(多YY有益身体健康).

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    template<class T>inline void read(T &num) {
        register char ch; register int flg = 1;
        while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
        for(num=0; isdigit(ch); num=num*10+ch-'0', ch=getchar());
        num *= flg;
    }
    const int MAXN = 2005;
    const int C = 26;
    char A[MAXN], B[MAXN];
    int f[MAXN][MAXN];
    namespace task1 {
        inline void solve() {
            int ans = MAXN-1;
            for(int i = 1; A[i]; ++i) {//字串的右端点
                int mx = 0;
                for(int j = 1; B[j]; ++j)
                    if(A[i] == B[j])
                        mx = max(mx, f[i][j] = f[i-1][j-1] + 1);
                if(mx < i) ans = min(ans, mx+1);
            }
            printf("%d
    ", (A[ans] && B[ans]) ? ans : -1);
        }
    }
    namespace task2 {
        inline void solve() {
            int ans = MAXN-1;
            for(int i = 1; A[i]; ++i) {//字串的右端点
                int mx = 0;
                for(int j = 1; B[j]; ++j) {
                    if(A[i] == B[j])
                        mx = max(mx, f[i][j] = f[i-1][j-1] + 1);
                    else mx = max(mx, f[i][j] = f[i][j-1]);
                }
                if(mx < i) ans = min(ans, mx+1);
            }
            printf("%d
    ", (A[ans] && B[ans]) ? ans : -1);
        }
    }
    namespace task3 {
        int sz, last, len[MAXN<<1], link[MAXN<<1], ch[MAXN<<1][C], dp[MAXN<<1];
        inline void init() {
            memset(dp, 0x3f, sizeof dp);
            sz = last = 0; ++sz;
            len[0] = dp[0] = 0;
            link[0] = -1;
            //memset(ch, 0, sizeof ch);
        }
        inline void insert(int c) {
            int cur = sz++, p;
            len[cur] = len[last] + 1;
            for(p = last; ~p && !ch[p][c]; p = link[p]) ch[p][c] = cur;
            if(p == -1) link[cur] = 0;
            else {
                int q = ch[p][c];
                if(len[p] + 1 == len[q]) link[cur] = q;
                else {
                    int clone = sz++;
                    len[clone] = len[p] + 1;
                    link[clone] = link[q];
                    memcpy(ch[clone], ch[q], sizeof ch[q]);
                    for(; ~p && ch[p][c] == q; p = link[p]) ch[p][c] = clone;
                    link[cur] = link[q] = clone;
                }
            }
            last = cur;
        }
        inline void solve() {
            init();
            for(int i = 1; B[i]; ++i) insert(B[i]-'a');
            int ans = MAXN-1;
            for(int i = 1, c; A[i]; ++i) {
                c = A[i]-'a';
                for(int j = 0; j < sz; ++j) {
                    if(ch[j][c]) dp[ch[j][c]] = min(dp[ch[j][c]], dp[j] + 1);
                    else ans = min(ans, dp[j] + 1);
                }
            }
            printf("%d
    ", (A[ans] && B[ans]) ? ans : -1);
        }
    }
    namespace task4 {
        int nxt[MAXN][C], pos[C], dp[MAXN];
        inline void solve() {
            int len = strlen(B+1);
            memset(dp, 0x3f, sizeof dp);
            dp[0] = 0;
            for(int i = len; ~i; --i) { //要循环到0
                for(int c = 0; c < 26; ++c)
                    nxt[i][c] = pos[c];
                if(i) pos[B[i]-'a'] = i;
            }
            int ans = MAXN-1;
            for(int i = 1, c; A[i]; ++i) {
                c = A[i]-'a';
                for(int j = len; ~j; --j) //要循环到0
                    if(nxt[j][c]) dp[nxt[j][c]] = min(dp[nxt[j][c]], dp[j] + 1);
                    else ans = min(ans, dp[j] + 1);
            }
            printf("%d
    ", (A[ans] && B[ans]) ? ans : -1);
        }
    }
    int main() {
        scanf("%s%s", A+1, B+1);
        task1::solve();
        task2::solve();
        task3::solve();
        task4::solve();
    }
    
    
  • 相关阅读:
    110. 平衡二叉树-前序遍历-简单
    207. 课程表-有向图判断有无环状-中等难度
    java错误集锦
    199. 二叉树的右视图-二叉树,dfs,从右往左遍历-中等难度
    114. 二叉树展开为链表-二叉树,dfs-中等难度
    236. 二叉树的最近公共祖先-中序遍历-中等难度
    Kendo ui 入门知识点
    Css样式压缩、美化、净化工具 源代码
    Linq与Lambda常用查询语法
    15个超强悍的CSS3圆盘时钟动画赏析
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039320.html
Copyright © 2011-2022 走看看