BZOJ 2085 [POI2010] Hamsters
题面
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的更多相关文章
- BZOJ 2085 luogu P3502 [POI2010]Hamsters (KMP、Floyd、倍增)
数组开小毁一生-- 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2085 这题在洛谷上有个条件是"互不包含",其实 ...
- BZOJ 2080: [Poi2010]Railway 双栈排序
2080: [Poi2010]Railway Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 140 Solved: 35[Submit][Statu ...
- [poi2010]Hamsters
题意:Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算.现在Tz想好了要出现多少个名字,请你求出最短的 ...
- BZOJ 2096: [Poi2010]Pilots( set )
用个set维护就可以水过去...O(NlogN) 应该可以用单调队列O(N).... --------------------------------------------------------- ...
- BZOJ 2096([Poi2010]Pilots-单调队列-差值)
2096: [Poi2010]Pilots Time Limit: 30 Sec Memory Limit: 162 MB Submit: 190 Solved: 97 [ Submit][ ...
- bzoj 2095: [Poi2010]Bridges [混合图欧拉回路]
2095: [Poi2010]Bridges 二分答案,混合图欧拉路判定 一开始想了一个上下界网络流模型,然后发现不用上下界网络流也可以 对于无向边,强制从\(u \rightarrow v\),计算 ...
- BZOJ 2084: [Poi2010]Antisymmetry [Manacher]
2084: [Poi2010]Antisymmetry Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 609 Solved: 387[Submit] ...
- BZOJ 2083: [Poi2010]Intelligence test [vector+二分]
2083: [Poi2010]Intelligence test Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 469 Solved: 227[Su ...
- 【刷题】BZOJ 2096 [Poi2010]Pilots
Description Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值.耍畸形一个人是 ...
随机推荐
- LeetCode(232) Implement Queue using Stacks
题目 Implement the following operations of a queue using stacks. push(x) – Push element x to the back ...
- redis--py链接redis【转】
请给原作者点赞--> 原文链接 一.redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链 ...
- 关于前台jsp页面的js取值问题
在后程序中传一个字符串到前台页面上,后台代码model.addAttribute("ccc", "cccc"); 在页面js上用下面两种方法取值 1. var ...
- 25、Base64
Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3 ...
- 大数据学习——scala类相关操作
1 类的定义 package com /** * Created by Administrator on 2019/6/3. */ //类并不用声明为public. class Person { // ...
- [python][oldboy]关键字参数和位置参数,默认参数,可变长参数(无名,有名)
关键字参数和位置参数是在函数调用的时候定义 关键字参数是以键-值对出现,无序,多一个不行,少一个不行 位置参数,有序,多一个不行,少一个不行 混搭:所有位置参数必须在关键字参数的左边 默认参数是在函数 ...
- phpcms 后台也名称
announce 公告 show.html 内容页 comment 评论 show_list.html 内容页评论列表 list.html 评论列表 content 内容模型 category.htm ...
- 内存分配机制malloc&&alloca&&realloc
<1>从静态存储区域分配. 内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量.static变量.<2>在栈上创建 在执 ...
- 骨牌覆盖问题总结!hihoCoder/ NYOJ-1273宣传墙1151
本想着做一下第九届河南省省赛题,结果被这个类似骨牌覆盖的题卡住了,队友然我去hihoCoder上老老实实把骨牌覆盖一.二.三做完,这题就没什么问题了.虽然很不情愿,但还是去见识了一下. 骨牌覆盖问题 ...
- setsockopt等高级使用
参考: setsockopt函数使用http://hi.baidu.com/yelangdefendou/item/74161d0f384abd3c4ac4a316http://blog.csdn.n ...