首页 > 代码库 > [poi2010]Hamsters
[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:
1 /* 2 * Author: Yzcstc 3 * Created Time: 2014/11/12 20:54:48 4 * File Name: hamsters.cpp 5 */ 6 #include<cstdio> 7 #include<iostream> 8 #include<cstring> 9 #include<cstdlib>10 #include<cmath>11 #include<algorithm>12 #include<string>13 #include<map>14 #include<set>15 #include<vector>16 #include<queue>17 #include<stack>18 #include<ctime>19 #define M0(x) memset(x, 0, sizeof(x))20 #define repf(i, a, b) for (int i = (a); i <= (b); ++i)21 #define Inf 0x7fffffff22 #define M 1000723 using namespace std;24 typedef long long ll;25 const int maxn = 204;26 int n, m;27 char str[120000];28 vector<int> hs[210];29 int sz[maxn], pw[120000];30 ll A[maxn][maxn], B[maxn][maxn];31 ll s[maxn], tmp[maxn];32 33 inline int Hash(const int &p, const int& l, const int& r){34 return hs[p][r] - hs[p][l-1] * pw[r-l+1];35 }36 37 void init(){38 int len, v;39 repf(i, 1, n){40 scanf("%s", str + 1);41 sz[i] = len = strlen(str + 1);42 hs[i].push_back(v = 0);43 repf(j, 1, len) 44 v = v * M + str[j], hs[i].push_back(v);45 }46 }47 48 void modify(ll *s, ll A[][maxn]){49 memset(tmp, 0x3f, sizeof(tmp));50 // cout << tmp[0] << endl;51 for (int i = 1; i <= n; ++i)52 for (int j = 1; j <= n; ++j)53 tmp[j] = min(tmp[j], s[i] + A[i][j]);54 repf(i, 1, n) s[i] = tmp[i];55 }56 57 void modify(ll A[][maxn]){58 memset(B, 0x3f, sizeof(B));59 repf(k, 1, n) repf(i, 1, n) repf(j, 1, n)60 B[i][j] = min(B[i][j], A[i][k] + A[k][j]); 61 repf(i, 1, n) repf(j, 1, n) A[i][j] = B[i][j]; 62 }63 64 void quick(int n){65 for (;n>0; n>>=1){66 if (n & 1) modify(s, A);67 modify(A);68 } 69 }70 71 void solve(){72 repf(i, 1, n) repf(j, 1, n){73 A[i][j] = sz[j]; 74 for (int k = max(2, sz[i]-sz[j]+2); k <= sz[i]; ++k)75 if (Hash(i, k, sz[i]) == Hash(j, 1, sz[i]-k+1)){76 A[i][j] = sz[j] - (sz[i]-k+1); break;77 }78 }79 repf(i, 1, n) s[i] = sz[i];80 quick(--m);81 ll ans = 1LL<<62;82 // cout << ans << endl;83 repf(i, 1, n) ans = min(ans, s[i]);84 cout << ans << endl;85 } 86 87 int main(){88 pw[0] = 1;89 repf(i, 1, 100000) pw[i] = pw[i-1] * M; 90 while (scanf("%d%d", &n, &m) != EOF){91 init();92 solve();93 }94 return 0;95 }
[poi2010]Hamsters
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。