zoukankan      html  css  js  c++  java
  • P3041 [USACO12JAN]视频游戏的连击Video Game Combos

    P3041 [USACO12JAN]视频游戏的连击Video Game Combos

    https://www.luogu.org/problemnew/show/P3041

    分析:

      AC自动机。

      建立AC自动机,然后dp[i][j]表示经过了i个字符,到达自动机上j这个位置,的得分。

      那么dp[i-1][j] + val[ch[j][k]] -> dp[i][ch[j][k]]。

      表示从j点,往前走一步,加上新加一个字符产生的贡献。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 
     5 const int N = 550;
     6 int ch[N][3], fail[N], last[N], val[N], f[1010][N], q[N], L, R, Index = 1;
     7 char s[22];
     8 
     9 void Insert(char *s) {
    10     int u = 0, len = strlen(s);
    11     for (int i=0; i<len; ++i) {
    12         int c = s[i] - 'A';
    13         if (!ch[u][c]) ch[u][c] = ++Index;
    14         u = ch[u][c];
    15     }
    16     val[u] ++;
    17 }
    18 void build() {
    19     L = 1, R = 0; fail[0] = 0;
    20     for (int c=0; c<3; ++c) {
    21         int u = ch[0][c];
    22         if (u) q[++R] = u, fail[u] = last[u] = 0;
    23     }
    24     while (L <= R) {
    25         int u = q[L++];
    26         for (int c=0; c<3; ++c) {
    27             int v = ch[u][c];
    28             if (!ch[u][c]) {
    29                 ch[u][c] = ch[fail[u]][c];
    30                 continue;
    31             }
    32             q[++R] = v;
    33             int p = fail[u];
    34             while (p && !ch[p][c]) p = fail[p];
    35             fail[v] = ch[p][c];
    36         }
    37         val[u] += val[fail[u]];
    38     }
    39 }
    40 
    41 int main () {
    42     
    43     int n,m; cin >> n >> m;
    44     for (int i=1; i<=n; ++i) {
    45         scanf("%s",s);
    46         Insert(s);
    47     }
    48     build();
    49     memset(f, -0x3f, sizeof(f));
    50     f[0][0] = 0;
    51 
    52     // f[i][j]表示用了i个字符,在自动机的j号位置,可以得多少分 
    53     for (int i=1; i<=m; ++i) 
    54         for (int j=0; j<=Index; ++j)
    55             for (int k=0; k<3; ++k) 
    56                 f[i][ch[j][k]] = max(f[i][ch[j][k]], f[i-1][j]+val[ch[j][k]]);
    57                 // 从j这个位置,经过字符k到达的点的得分为 经过i-1个点到j的得分+经过i个点到ch[j][k]的得分 
    58 
    59     int Ans = 0;
    60     for (int i=0; i<=Index; ++i) Ans = max(Ans, f[m][i]);
    61     cout << Ans;
    62         
    63     return 0;
    64 }
  • 相关阅读:
    Loki 初体验
    柠檬研究院及第一期活动预告
    Apache SkyWalking 为.NET Core带来开箱即用的分布式追踪和应用性能监控
    聊聊AspectCore动态代理中的拦截器
    使用AspectCore动态代理
    AspectCore中的IoC容器和依赖注入
    AspectCore.Extension.Reflection : .NET Core反射扩展库
    Asp.Net Core轻量级Aop解决方案:AspectCore
    [精品书单] C#/.NET 学习之路——从入门到放弃
    创建vue项目
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9356599.html
Copyright © 2011-2022 走看看