题意: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的更多相关文章

  1. BZOJ2085 : [Poi2010]Hamsters

    设g[i][j]为i串至少加上几个字符后才能包含j,可以通过Hash求出. 然后就是求经过m-1条边的最短路,用倍增加速Floyed即可,时间复杂度$O(n^3\log m)$. #include&l ...

  2. 【bzoj2085】[Poi2010]Hamsters Hash+倍增Floyd

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

  3. BZOJ 2085 [POI2010] Hamsters

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

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

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

  5. bzoj2085 [Poi2010]Hamsters 矩阵快速幂+字符串hash

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2085 题解 考虑暴力 DP 的做法.令 \(dp[i][j]\) 表示以 \(j\) 为开头的 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. 倍增&矩阵乘法 专题复习

    倍增&矩阵乘法 专题复习 PreWords 这两个基础算法我就不多说啦,但是还是要介绍一下" 广义矩阵 "乘法 其实就是把矩阵换成取\(max\),然后都一样... 据神仙 ...

  8. 安徽师大附中%你赛day6 T3 Hamsters [POI2010]CHO-Hamsters 解题报告

    [POI2010]CHO-Hamsters 题意: 给出n个互不包含的字符串,要求你求出一个最短的字符串S,使得这n个字符串在S中总共至少出现m次,问S最短是多少? 范围: \(1 \le n \le ...

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

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

随机推荐

  1. 利用Kinect将投影变得可直接用手操控

    Finally 总算是到了这一天了!假期里算法想不出来,或者被BUG折磨得死去活来的时候,总是YY着什么时候能心情愉快地坐在电脑前写一篇项目总结,今天总算是抽出时间来总结一下这神奇的几个月. 现在回过 ...

  2. linux 下进程通讯详解

    linux 下进程通讯方法主要有以下六种: 1.管道 2.信号 3.共享内存 4.消息队列 5.信号量 6.socket

  3. H5学习系列之Audio和Video

    1.视频文件:音频轨道.视频轨道和一些元数据(视频封面.标题.子标题.字幕等相关信息). 2.目前H5还不支持的:流式音频和视频(H5对视频的支持只限于加载的全部媒体文件).H5的媒体收到跨域资源共享 ...

  4. [Linux] mail 命令,进入邮箱及删除邮件

    1. 命令行输入mail 2. 删除邮件 d 删除当前邮件,指针下移: d 1 删除标号为1的邮件: d 2-4 删除标号2到4的邮件: 3. 保存 q 退出mail命令平台,保存之前的操作,比如删除 ...

  5. rem介绍

    手机端开发,一般以320px宽为最低标题.市场上的手机,大多数是360px宽. 20px=1rem是最容易换算的,基本上可以口算,除以2并缩小十倍.1px/20=0.05rem.两位小数就可以除尽了. ...

  6. DDX_Text ()函数 C++

    DDX_Text()函数管理着对话框.表格视或控件视对象中的编辑控件与对话框.表格视或控件视对象的CString型数据成员之间的int,UINT,long,DWORD,CString,float或do ...

  7. MySQL创建一个具有root权限的用户

    grant all privileges on *.* to 'user'@'host' identified by 'password' WITH GRANT OPTION MAX_QUERIES_ ...

  8. C#捕获c++异常

    摘自:http://bbs.csdn.net/topics/390665130 .net 40 中,c# 默认情况下只处理SEH的异常.不处理CSE的异常.若你要捕获这类的异常. [HandlePro ...

  9. 下拉框数据的动态选择,类似级联ajax刷新数据

    简单的两个下拉列表,第二个中的数据与第一个下拉框相关: --------------------var selected = $(this).children('option:selected').v ...

  10. c++11 实现单例模式

    C++11出来后,里面新增加了好多好用的功能 下面的单例就是使用了C++11中的标准库中的mutex和unique_prt 进行内存管理的. 此单例模式不用担心内存的释放问题 #pragma once ...