题面

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. STM32F407VET6之IAR之ewarm7.80.4工程建立(基于官方固件库1.6版本) 的工程文件目录

    最后整理结构如下所示,├─cmsis│ startup_stm32f401xx.s│ startup_stm32f40xx.s│ startup_stm32f40_41xxx.s│ startup_s ...

  2. 安装repo

    $ sudo apt-get install curl -y$ curl "http://android.git.linaro.org/gitweb?p=tools/repo.git;a=b ...

  3. SQL_4_函数

    在SQL的函数中可以执行一些诸如对某一些进行汇总或将一个字符串中的字符转换为大写的操作等: 函数有:汇总函数.日期与时间函数.数学函数.字符函数.转换函数与其他函数. 汇总函数 这是一组函数,它们返回 ...

  4. selenium2-框架思想介绍

    为什么要有框架? 可维护性 提高编写脚本效率 提高脚本的可读性 框架的几大要素: 1. driver管理 2. 脚本 3. 数据 4. 元素对象 5. Log 6. 报告 7. 运行机制 8. 失败用 ...

  5. 知名游戏引擎公司Havok发布免费3D移动游戏引擎“Project Anarchy”

    自EA发布“寒霜”引擎(Frostbite Engine)移动版后,知名游戏引擎公司Havok也发布了免费的3D移动游戏引擎“Project Anarchy”. 据悉,6月底时候,Intel旗下知名游 ...

  6. NOJ——1627Alex’s Game(II)(尺取)

    [1627] Alex’s Game(II) 时间限制: 2000 ms 内存限制: 65535 K 问题描述 Alex likes to play with one and zero as you ...

  7. bzoj4717 改装 模拟+二分

    Description [题目背景] 小Q最近喜欢上了一款游戏,名为<舰队connection>,在游戏中,小Q指挥强大的舰队南征北战,从而成为了一名dalao.在游戏中,不仅船只能力很重 ...

  8. [暑假集训--数论]poj2657 Comfort

    Description A game-board consists of N fields placed around a circle. Fields are successively number ...

  9. linux监控平台搭建-内存

    linux监控平台搭建-内存 上一篇文章说的硬盘.就写一下.更加重要的东西.在手机上面是RAM.机器是memory.内存是按照字节编址.每个地址的存储单元可以存放8bit的数据.cpu 通过内存地址获 ...

  10. 百度网络监控实战:NetRadar横空出世(上)

    原文:https://mp.weixin.qq.com/s/VBShicsqReDtureKAdEgDA 转自订阅号「AIOps智能运维」,已授权运维帮转发 作者简介:运小贝,百度高级研发工程师 负责 ...