• BZOJ 1559: [JSOI2009]密码( AC自动机 + 状压dp )


    建AC自动机后, dp(x, y, s)表示当前长度为x, 在结点y, 包括的串的状态为s的方案数, 转移就在自动机上走就行了. 对于输出方案, 必定是由给出的串组成(因为<=42), 所以直接暴搜答案. 数据范围很小, 可以AC(复杂度懒得算了....)

    ------------------------------------------------------------------------------------------------

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
     
    using namespace std;
     
    typedef long long ll;
    #define b(x) (1 << (x))
    #define C(c) (c - 'a')
     
    const int maxn = 11;
     
    int L, N, Com[maxn][maxn], lth[maxn], V[maxn], R[45], cnt;
    ll dp[2][100][b(maxn)];
    char S[maxn][maxn], res[45][30];
    bool F[maxn];
     
    struct Node {
    Node *ch[26], *f;
    int Id, n;
    } pool[100], *pt = pool, *Root, *q[100];
     
    void Init() {
    scanf("%d%d", &L, &N);
    (Root = pt++)->Id = 0;
    int idn = Root->n = 0;
    for(int i = 0; i < N; i++) {
    scanf("%s", S[i]);
    lth[i] = strlen(S[i]);
    Node* t = Root;
    for(int j = 0; j < lth[i]; j++) {
    if(!t->ch[C(S[i][j])]) {
    pt->Id = ++idn, pt->n = 0;
    t->ch[C(S[i][j])] = pt++;
    }
    t = t->ch[C(S[i][j])];
    }
    t->n |= b(i);
    }
    for(int i = 0; i < N; i++)
    for(int j = 0; j < N; j++) {
    int &v = Com[i][j];
    for(v = min(lth[i], lth[j]); v; v--) {
    bool F = true;
    int a = lth[i] - v, b = 0;
    while(a < lth[i]) {
    if(S[i][a] != S[j][b]) {
    F = false;
    break;
    }
    a++, b++;
    }
    if(F) break;
    }
    }
    cnt = 0;
    }
     
    void Build() {
    int h = 0, t = 0;
    (q[t++] = Root)->f = NULL;
    while(h < t) {
    Node* o = q[h++];
    for(int i = 0; i < 26; i++) if(o->ch[i]) {
    Node* f = o->f;
    while(f && !f->ch[i]) f = f->f;
    o->ch[i]->f = f ? f->ch[i] : Root;
    q[t++] = o->ch[i];
    }
    }
    }
     
    void DFS(int x, int len) {
    if(x == N) {
    if(len == L) {
    int p = 0;
    for(int i = 0; i < N; i++)
    for(int j = i ? Com[V[i - 1]][V[i]] : 0; j < lth[V[i]]; j++)
    res[cnt][p++] = S[V[i]][j];
    cnt++;
    }
    return;
    }
    for(int i = 0; i < N; i++) if(!F[i]) {
    F[V[x] = i] = true;
    DFS(x + 1, len + lth[i] - Com[V[x - 1]][i]);
    F[i] = false;
    }
    }
     
    bool Cmp(const int &l, const int &r) {
    return strcmp(res[l], res[r]) < 0;
    }
     
    void Work() {
    int c = 0, p = 1, h = 0, t = 0, S = b(N) - 1;
    q[t++] = Root;
    while(h < t) {
    Node* o = q[h++];
    if(o->f) o->n |= o->f->n;
    for(int i = 0; i < 26; i++)
    if(o->ch[i]) q[t++] = o->ch[i];
    }
    memset(dp[c], 0, sizeof dp[c]);
    dp[c][0][0] = 1;
    for(int i = 0; i < L; i++) {
    swap(c, p);
    memset(dp[c], 0, sizeof dp[c]);
    for(int r = 0; r < t; r++)
    for(int s = b(N); s--; ) if(dp[p][q[r]->Id][s]) {
    for(int j = 0; j < 26; j++) {
    Node* o = q[r];
    while(o && !o->ch[j]) o = o->f;
    o = o ? o->ch[j] : Root;
    dp[c][o->Id][s | o->n] += dp[p][q[r]->Id][s];
    }
    }
    }
    ll ans = 0;
    for(int i = 0; i < t; i++)
    ans += dp[c][q[i]->Id][S];
    printf("%lld ", ans);
    if(ans > 42) return;
    memset(F, 0, sizeof F);
    for(int i = 0; i < N; i++)
    F[V[0] = i] = true, DFS(1, lth[i]), F[i] = false;
    for(int i = 0; i < ans; i++) 
    res[R[i] = i][L] = '';
    sort(R, R + ans, Cmp);
    for(int i = 0; i < ans; i++)
    printf("%s ", res[R[i]]);
    }
     
    int main() {
    Init();
    Build();
    Work();
    return 0;
    }

    -----------------------------------------------------------------------------------------------

    1559: [JSOI2009]密码

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 675  Solved: 213
    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    10 2
    hello
    world

    Sample Output

    2
    helloworld
    worldhello

    HINT

    Source

  • 相关阅读:
    程序员常用英语词汇
    声明式编程与命令式编程
    vue 常用ui组件库
    Vue 组件之间传值
    vscode插件之背景插件(background)
    iconfont的使用
    CSS3 @font-face 规则
    CSS抗锯齿 font-smoothing 属性介绍
    new Image 读取宽高为0——onload
    js的for循环中出现异步函数,回调引用的循环值始终是最后的值
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5153664.html
Copyright © 2020-2023  润新知