题面

Description

Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算。现在Tz想好了要出现多少个名字,请你求出最短的字母序列的长度是多少。

Input

输入:第一行n(1<=n<=200)和m(1<=m<=10的9此方),n表示有多少个仓鼠,m表示Tz希望出现名字的次数,接下来n行,每行都是仓鼠的名字(中间没有空格)。

Output

输出:一行,最短的字母序列的长度。

Sample Input

  1. 4 5
  2. monika
  3. tomek
  4. szymon
  5. bernard
  6. Sample Output
  7. 23

Sample Output

  1. 23

题目大意

略.

题解

这一题的题面漏了一个条件: 字符串之间两两不相包含. 由于\(n \le 200\), 不难想到让这些名字两两作一次KMP, 得到一个转移矩阵. 我们考虑如何让\(m\)个名字在所求的串中出现. 建立一个初始矩阵: 对角线为每个字符串的长度, 其余位置均为\(+\infty\). 对初始矩阵与转移矩阵作\(m - 1\)次转移(使用倍增的方法, 类似于快速幂, 但不是矩阵乘法, 而是对应的行向量和列向量加起来取\(\min\)值). 得到的矩阵中, \(res_{i j}\)表示开始第一个名字为\(i\), 最后出现的名字为\(j\)的需要的最少字符数量.

在\(res_{n \times n}\)中取min即可.

一些细节需要注意, 已经在代码中标注.

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. const int N = 200, LEN = (int)1e5;
  5. const long long INF = (long long)1e15;
  6. namespace KMP
  7. {
  8. inline void initialize(char *str, int len, int *pre)
  9. {
  10. pre[0] = -1;
  11. for(int i = 1; i < len; ++ i)
  12. {
  13. int p = pre[i - 1];
  14. for(; ~ p && str[p + 1] ^ str[i]; p = pre[p]);
  15. if(str[p + 1] == str[i])
  16. ++ p;
  17. pre[i] = p;
  18. }
  19. }
  20. inline int match(char *s, int len, char *t, int *pre)
  21. {
  22. int p = -1;
  23. for(int i = 0; i < len; ++ i)
  24. {
  25. for(; ~ p && t[p + 1] ^ s[i]; p = pre[p]); // 假如s和t是同一个串的话, 则要特判
  26. if(t[p + 1] == s[i] && (s != t || p + 1 < i))
  27. ++ p;
  28. }
  29. return p + 1;
  30. }
  31. }
  32. struct matrix
  33. {
  34. long long a[N][N];
  35. int n;
  36. inline matrix(int _n)
  37. {
  38. n = _n;
  39. }
  40. inline matrix friend operator *(const matrix &A, const matrix &B)
  41. {
  42. static matrix res(A.n);
  43. for(int i = 0; i < A.n; ++ i)
  44. for(int j = 0; j < A.n; ++ j)
  45. {
  46. res.a[i][j] = INF;
  47. for(int k = 0; k < A.n; ++ k)
  48. res.a[i][j] = std::min(A.a[i][k] + B.a[k][j], res.a[i][j]);
  49. }
  50. return res;
  51. }
  52. };
  53. inline void power(matrix A, int x, matrix &res)
  54. {
  55. for(; x; x >>= 1, A = A * A)
  56. if(x & 1)
  57. res = res * A;
  58. }
  59. int main()
  60. {
  61. #ifndef ONLINE_JUDGE
  62. freopen("BZOJ2085.in", "r", stdin);
  63. // freopen("BZOJ2085.out", "w", stdout);
  64. #endif
  65. int n, m;
  66. scanf("%d%d", &n, &m);
  67. static char str[N][LEN];
  68. static int pre[N][LEN];
  69. for(int i = 0; i < n; ++ i)
  70. scanf("%s", str[i]), KMP::initialize(str[i], strlen(str[i]), pre[i]);
  71. static matrix A(n);
  72. for(int i = 0; i < n; ++ i)
  73. for(int j = 0; j < n; ++ j)
  74. A.a[i][j] = strlen(str[j]) - KMP::match(str[i], strlen(str[i]), str[j], pre[j]);
  75. static matrix res(n);
  76. for(int i = 0; i < n; ++ i)
  77. for(int j = 0; j < n; ++ j)
  78. res.a[i][j] = i ^ j ? INF : strlen(str[i]);
  79. power(A, m - 1, res); // m要减1
  80. long long ans = INF;
  81. for(int i = 0; i < n; ++ i)
  82. for(int j = 0; j < n; ++ j)
  83. ans = std::min(ans, res.a[i][j]);
  84. printf("%lld", ans);
  85. }

BZOJ 2085 [POI2010] Hamsters的更多相关文章

  1. BZOJ 2085 luogu P3502 [POI2010]Hamsters (KMP、Floyd、倍增)

    数组开小毁一生-- 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2085 这题在洛谷上有个条件是"互不包含",其实 ...

  2. BZOJ 2080: [Poi2010]Railway 双栈排序

    2080: [Poi2010]Railway Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 140  Solved: 35[Submit][Statu ...

  3. [poi2010]Hamsters

    题意:Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算.现在Tz想好了要出现多少个名字,请你求出最短的 ...

  4. BZOJ 2096: [Poi2010]Pilots( set )

    用个set维护就可以水过去...O(NlogN) 应该可以用单调队列O(N).... --------------------------------------------------------- ...

  5. BZOJ 2096([Poi2010]Pilots-单调队列-差值)

    2096: [Poi2010]Pilots Time Limit: 30 Sec   Memory Limit: 162 MB Submit: 190   Solved: 97 [ Submit][ ...

  6. bzoj 2095: [Poi2010]Bridges [混合图欧拉回路]

    2095: [Poi2010]Bridges 二分答案,混合图欧拉路判定 一开始想了一个上下界网络流模型,然后发现不用上下界网络流也可以 对于无向边,强制从\(u \rightarrow v\),计算 ...

  7. BZOJ 2084: [Poi2010]Antisymmetry [Manacher]

    2084: [Poi2010]Antisymmetry Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 609  Solved: 387[Submit] ...

  8. BZOJ 2083: [Poi2010]Intelligence test [vector+二分]

    2083: [Poi2010]Intelligence test Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 469  Solved: 227[Su ...

  9. 【刷题】BZOJ 2096 [Poi2010]Pilots

    Description Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值.耍畸形一个人是 ...

随机推荐

  1. CodeForces 567F DP Mausoleum

    本着只贴代码不写分析的题解是在耍流氓的原则,还是决定写点分析. 思路很清晰,参考的官方题解,一下文字仅对题解做一个简要翻译. 题意: 有1~n这n个数,每个数用两次.构成一个长为2n的序列,而且要求序 ...

  2. JBuilder生成Exe

    首先保证工程可以通过绿箭头执行 然后在File菜单中选择New,先建立Archive下的Application 接下来的界面中大部分可以直接选择“Next”,除了下面的第3步,会询问是否需要将工程引用 ...

  3. LoadRunner11使用方法以及注意点收集

    一:安装loadrunner http://jingyan.baidu.com/article/f7ff0bfc1cc82c2e26bb13b7.html http://www.cnblogs.com ...

  4. Selenium WebDriver-actionchain模拟键盘左键长按

    #encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webdriver i ...

  5. [svn学习篇]svn使用教程

    http://www.cnblogs.com/longshiyVip/p/4905901.html http://blog.csdn.net/dily3825002/article/details/6 ...

  6. 如何使用Python的logging模块

    几个学习连接: Python官方链接: https://docs.python.org/3.4/library/logging.html?highlight=logging 翻译(不过是2.3版本的) ...

  7. iOS学习笔记48-Swift(八)反射

    一.Swift反射 所谓反射就是可以动态获取类型.成员信息,在运行时可以调用方法.属性等行为的特性. 在使用OC开发时很少强调其反射概念,因为OC的Runtime要比其他语言中的反射强大的多.不过在S ...

  8. Apache2 FastCGI C Demo

    安装依赖 sudo apt-get install libapache2-mod-fastcgi a2enmod fastcgi sudo apt-get install libfcgi-dev li ...

  9. 用-webkit-box-reflect制作倒影

    1.只在webkit内核的浏览器上有效果 2.语法: -webkit-box-reflect: <direction> <offset> <mask-box-image& ...

  10. hihoCoder #1117 战争年代

    题目大意 对一棵树的节点染色.初始时每个点都染成颜色 $0$,然后进行 $m$ 轮操作.第 $i$ 轮操作:从 $[0,d_i]$ 中随机选出一个整数 $d$,将距离点 $x_i$ 不超过 $d$ 的 ...