[poi2010]Hamsters
题意:Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算。现在Tz想好了要出现多少个名字,请你求出最短的字母序列的长度是多少。(n <= 200, m <= 1e9)
思路:首先可以处理出g[a][b]表示b接在a后面的长度(即重复部分之前都不算)
那么就可以转化成求长度m-1的最短路。
假设dis[i][a][b]为经过i步a走到b的最短路,那么dis[i][a][b] = min(dis[i/2][a][c] + dis[i-i/2][c][b]) (1<=c<=n)
那么是不是就可以利用快速幂的思想了。。
前面求g[a][b]可利用hash判断是否一样
code:
/*
* Author: Yzcstc
* Created Time: 2014/11/12 20:54:48
* File Name: hamsters.cpp
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<ctime>
#define M0(x) memset(x, 0, sizeof(x))
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define Inf 0x7fffffff
#define M 10007
using namespace std;
typedef long long ll;
const int maxn = ;
int n, m;
char str[];
vector<int> hs[];
int sz[maxn], pw[];
ll A[maxn][maxn], B[maxn][maxn];
ll s[maxn], tmp[maxn]; inline int Hash(const int &p, const int& l, const int& r){
return hs[p][r] - hs[p][l-] * pw[r-l+];
} void init(){
int len, v;
repf(i, , n){
scanf("%s", str + );
sz[i] = len = strlen(str + );
hs[i].push_back(v = );
repf(j, , len)
v = v * M + str[j], hs[i].push_back(v);
}
} void modify(ll *s, ll A[][maxn]){
memset(tmp, 0x3f, sizeof(tmp));
// cout << tmp[0] << endl;
for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j)
tmp[j] = min(tmp[j], s[i] + A[i][j]);
repf(i, , n) s[i] = tmp[i];
} void modify(ll A[][maxn]){
memset(B, 0x3f, sizeof(B));
repf(k, , n) repf(i, , n) repf(j, , n)
B[i][j] = min(B[i][j], A[i][k] + A[k][j]);
repf(i, , n) repf(j, , n) A[i][j] = B[i][j];
} void quick(int n){
for (;n>; n>>=){
if (n & ) modify(s, A);
modify(A);
}
} void solve(){
repf(i, , n) repf(j, , n){
A[i][j] = sz[j];
for (int k = max(, sz[i]-sz[j]+); k <= sz[i]; ++k)
if (Hash(i, k, sz[i]) == Hash(j, , sz[i]-k+)){
A[i][j] = sz[j] - (sz[i]-k+); break;
}
}
repf(i, , n) s[i] = sz[i];
quick(--m);
ll ans = 1LL<<;
// cout << ans << endl;
repf(i, , n) ans = min(ans, s[i]);
cout << ans << endl;
} int main(){
pw[] = ;
repf(i, , ) pw[i] = pw[i-] * M;
while (scanf("%d%d", &n, &m) != EOF){
init();
solve();
}
return ;
}
[poi2010]Hamsters的更多相关文章
- BZOJ2085 : [Poi2010]Hamsters
		
设g[i][j]为i串至少加上几个字符后才能包含j,可以通过Hash求出. 然后就是求经过m-1条边的最短路,用倍增加速Floyed即可,时间复杂度$O(n^3\log m)$. #include&l ...
 - 【bzoj2085】[Poi2010]Hamsters  Hash+倍增Floyd
		
题目描述 Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算.现在Tz想好了要出现多少个名字,请你求出最 ...
 - BZOJ 2085 [POI2010] Hamsters
		
题面 Description Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算.现在Tz想好了要出现多 ...
 - BZOJ 2085 luogu P3502 [POI2010]Hamsters (KMP、Floyd、倍增)
		
数组开小毁一生-- 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2085 这题在洛谷上有个条件是"互不包含",其实 ...
 - bzoj2085 [Poi2010]Hamsters  矩阵快速幂+字符串hash
		
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2085 题解 考虑暴力 DP 的做法.令 \(dp[i][j]\) 表示以 \(j\) 为开头的 ...
 - bzoj AC倒序
		
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
 - 倍增&矩阵乘法 专题复习
		
倍增&矩阵乘法 专题复习 PreWords 这两个基础算法我就不多说啦,但是还是要介绍一下" 广义矩阵 "乘法 其实就是把矩阵换成取\(max\),然后都一样... 据神仙 ...
 - 安徽师大附中%你赛day6 T3 Hamsters  [POI2010]CHO-Hamsters  解题报告
		
[POI2010]CHO-Hamsters 题意: 给出n个互不包含的字符串,要求你求出一个最短的字符串S,使得这n个字符串在S中总共至少出现m次,问S最短是多少? 范围: \(1 \le n \le ...
 - BZOJ 2080: [Poi2010]Railway 双栈排序
		
2080: [Poi2010]Railway Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 140 Solved: 35[Submit][Statu ...
 
随机推荐
- Activity启动模式
			
------siwuxie095 共4种启动模式:standard singleTop singleTask singleInstance 1.标准启动模式(standard) 也即默认的启动模式 ( ...
 - ios xib或storyBoard的那些小方法
			
今天看了一下xib里的一些小技巧,但是百度一搜的话,网上已经有人写过教程了,在这里我也就懒一下,不写那么详细了,就写一些如何百度的方法! 1."通过KVC修改占位文字的颜色" [t ...
 - JS产生随机数
			
<script> function GetRandomNum(Min,Max){ var Range = Max - Min; var Rand = Math.random() ...
 - JavaScript中关于时间的知识点
			
1.计算时间差,天数,小时数,余数 var begintime_ms = Date.parse(new Date(begintime.replace(/-/g, "/"))); / ...
 - Linux进程管理、任务管理
			
查看进程 Linux中的进程可以使用ps.pstree命令查看. 一般使用 ps aux (注意,没有短划线-:虽然加上不影响执行,只是会提示),还可以使用 ps -le,都是查看所有进程,区别在于显 ...
 - touchstart,touchmove判断手机中滑屏方向
			
滑动屏幕 touchstart:接触屏幕时触发,touchmove:活动过程触发,touchend:离开屏幕时触发 首先获取手接触屏幕时的坐标X,Y //获取接触屏幕时的X和Y$('body') ...
 - Java初学随笔
			
背景 狡兔三窟,在使用了近7-8年的C#后,考虑到云化的到来,还是要面向更多的语言与技术,近期决定学习scala,先从Java为跳板,最后达到学会并熟练 使用scala的目的. <核心技术> ...
 - 项目jar包管理,使用 .userlibraries 文件增加jar包的可移植性,明确jar包依赖,多项目共用jar包里
			
当一个普通的项目,在不适用maven 等jar包管理工具的时候,通常我都会直接把jar 包复制lib下,并且在build path 中直接添加额外jar包,或者使用user_libraries包所用的 ...
 - 【Java】:ehcache
			
ehcache是一个纯Java进程内缓存框架,是hibernate默认的Cacheprovider.(出自百度百科). 1. 快速2. 简单3. 多种缓存策略4. 缓存数据有两级:内存和磁盘,因此无需 ...
 - 设置secureCRT支持中文
			
将options菜单下面的session options 中的 appearance 标签页里面的 character encoding 选择UTF-8就可以.