题面

Description

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

Input

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

Output

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

Sample Input

4 5
monika
tomek
szymon
bernard
Sample Output
23

Sample Output

23

题目大意

略.

题解

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

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

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

#include <cstdio>
#include <cstring>
#include <algorithm> const int N = 200, LEN = (int)1e5;
const long long INF = (long long)1e15; namespace KMP
{
inline void initialize(char *str, int len, int *pre)
{
pre[0] = -1;
for(int i = 1; i < len; ++ i)
{
int p = pre[i - 1];
for(; ~ p && str[p + 1] ^ str[i]; p = pre[p]);
if(str[p + 1] == str[i])
++ p;
pre[i] = p;
}
} inline int match(char *s, int len, char *t, int *pre)
{
int p = -1;
for(int i = 0; i < len; ++ i)
{
for(; ~ p && t[p + 1] ^ s[i]; p = pre[p]); // 假如s和t是同一个串的话, 则要特判
if(t[p + 1] == s[i] && (s != t || p + 1 < i))
++ p;
}
return p + 1;
}
} struct matrix
{
long long a[N][N];
int n; inline matrix(int _n)
{
n = _n;
} inline matrix friend operator *(const matrix &A, const matrix &B)
{
static matrix res(A.n);
for(int i = 0; i < A.n; ++ i)
for(int j = 0; j < A.n; ++ j)
{
res.a[i][j] = INF;
for(int k = 0; k < A.n; ++ k)
res.a[i][j] = std::min(A.a[i][k] + B.a[k][j], res.a[i][j]);
}
return res;
}
}; inline void power(matrix A, int x, matrix &res)
{
for(; x; x >>= 1, A = A * A)
if(x & 1)
res = res * A;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("BZOJ2085.in", "r", stdin);
// freopen("BZOJ2085.out", "w", stdout);
#endif
int n, m;
scanf("%d%d", &n, &m);
static char str[N][LEN];
static int pre[N][LEN];
for(int i = 0; i < n; ++ i)
scanf("%s", str[i]), KMP::initialize(str[i], strlen(str[i]), pre[i]);
static matrix A(n);
for(int i = 0; i < n; ++ i)
for(int j = 0; j < n; ++ j)
A.a[i][j] = strlen(str[j]) - KMP::match(str[i], strlen(str[i]), str[j], pre[j]);
static matrix res(n);
for(int i = 0; i < n; ++ i)
for(int j = 0; j < n; ++ j)
res.a[i][j] = i ^ j ? INF : strlen(str[i]);
power(A, m - 1, res); // m要减1
long long ans = INF;
for(int i = 0; i < n; ++ i)
for(int j = 0; j < n; ++ j)
ans = std::min(ans, res.a[i][j]);
printf("%lld", ans);
}

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. holtek编程注意事项

    1.holtek单片机中断服务函数中函数调用里的参数不能传递地址,不然程序就会跑飞 2.holtek单片机尽量不要函数嵌套很多层,嵌套过多,会导致单片机复位

  2. Ubuntu 档案权限

    Linux文件属性:查看指令是:ls -al ls是list的意思,重点在显示档案的文件名与相关属性.而选项-al则表示列出所有的档案详细的权限与属性.

  3. 我的PC必装软件

    我的PC必装软件 TeXLive LaTeX套装 WinEdt LaTeX编辑器 PyCharm Python IDE Inkscape 矢量图制作,我根本不会用,但是常用来把SVG转成*.tex文件 ...

  4. MySQL可供选择的存储引擎

    备注:以下关于5.7版本的内容是来源于官方文档:https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html 以下关于5.6版本的内容,一部 ...

  5. 解决Failed with error: unable to access 'https://git.coding.net/chenmi1234/lianpos.git/': Couldn't resolve host 'git.coding.net'

    代码改变世界 github push 出现问题 Failed with error: unable to access 'https://git.coding.net/chenmi1234/lianp ...

  6. npm link & run npm script

    npm link & run npm script https://blog.csdn.net/juhaotian/article/details/78672390 npm link命令可以将 ...

  7. 【bzoj1592】[Usaco2008 Feb]Making the Grade 路面修整

    FJ打算好好修一下农场中某条凹凸不平的土路.按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也就是说,高度上升与高度下降的路段不能同时出现在修好的路中. 整条路被分成了N段,N个整数A_1, ...

  8. [转] Makefile 基础 (3) —— Makefile 书写规则

    该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客:(最原始版本) http://blog.csdn.net/haoel/article/details/2886 我转自 ...

  9. spoj 7001 Visible Lattice Points莫比乌斯反演

    Visible Lattice Points Time Limit:7000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Su ...

  10. hdu 6119 小小粉丝度度熊

    小小粉丝度度熊 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...