• [POI2010]CHO-Hamsters


    KMP暴力求出next数组后
    实际上是一个最短路问题,floyed搞一搞
    然而会TLE
    矩阵优化一下即可(倍增floyed)
    KMP在弱数据下可以AC。。正解请看其他人博客

    # include <stdio.h>
    # include <stdlib.h>
    # include <iostream>
    # include <algorithm>
    # include <string.h>
    # define IL inline
    # define RG register
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    
    IL ll Read(){
        RG char c = getchar(); RG ll x = 0, z = 1;
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
        return x * z;
    }
    
    int n, m, nxt[210][100010], len[210];
    char s[210][100010];
    struct Matrix{
        ll a[210][210];
        IL void Clear(){  Fill(a, 63);  }
        IL ll* operator [](RG int x){  return a[x];  }
        IL Matrix operator *(RG Matrix &B){
            RG Matrix C; C.Clear();
            for(RG int i = 0; i <= n; i++)
                for(RG int j = 0; j <= n; j++)
                    for(RG int k = 0; k <= n; k++)
                        C[i][k] = min(C[i][k], a[i][j] + B[j][k]);
            return C;
        }
    } ans, edge;
    
    int main(RG int argc, RG char* argv[]){
        edge.Clear(); ans.Clear();
        n = Read(); m = Read();
        for(RG int i = 1; i <= n; i++)
            scanf(" %s", s[i] + 1), len[i] = strlen(s[i] + 1);
        for(RG int k = 1; k <= n; k++)
            for(RG int i = 2, j = 0; i <= len[k]; i++){
                while(j && s[k][j + 1] != s[k][i]) j = nxt[k][j];
                if(s[k][j + 1] == s[k][i]) j++;
                nxt[k][i] = j;
            }
        for(RG int x = 1; x <= n; x++){
            edge[0][x] = len[x];
            for(RG int y = 1; y <= n; y++)
                for(RG int i = 2, j = 0; i <= len[x]; i++){
                    while(j && s[y][j + 1] != s[x][i]) j = nxt[y][j];
                    if(s[y][j + 1] == s[x][i]) j++;
                    if(i == len[x]) edge[x][y] = len[y] - j;
                }
        }
        for(RG int i = 0; i <= n; i++) ans[i][i] = 0;
        for(; m; m >>= 1, edge = edge * edge) if(m & 1) ans = ans * edge;
        RG ll min_len = 1e18;
        for(RG int i = 1; i <= n; i++) min_len = min(ans[0][i], min_len);
        printf("%lld
    ", min_len);
        return 0;
    }
    
  • 相关阅读:
    zoj 2876 Phone List
    zoj 2829 Beautiful Number
    zoj 2723 Semi-Prime(set)
    zoj 2835 Magic Square(set)
    zoj 2818 Root of the Problem
    zoj 2744 Palindromes
    zoj 1109 Language of FatMouse(map)
    zoj 2724 Windows Message Queue
    zoj 2722 Head-to-Head Match(两两比赛)
    zoj 2727 List the Books
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206388.html
Copyright © 2020-2023  润新知