标签:ble hashtable logs bzoj eth base 其他 pre can
题目链接 字符串折叠
区间DP。f[l][r]为字符串在区间l到r的最小值
正常情况下 f[l][r] = min(f[l][r], f[l][l + k - 1] + f[l + k][r]);
当l到r以k为周期时 f[l][r] = min(f[l][r], 2 + sz(k) + f[l][l + (r - l + 1) / k - 1]);
判重的时候为了方便我用了哈希……当然其他方法应该也是可以的~
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) typedef unsigned long long LL; const int N = 210; const int base = 233; int f[N][N], n; LL bin[N], Hash[N]; char s[N]; void Hashtable(){ bin[0] = 1; rep(i, 1, n) bin[i] = bin[i - 1] * base; rep(i, 1, n) Hash[i] = Hash[i - 1] * base + s[i]; } inline LL gethash(int l, int r){ return Hash[r] - Hash[l - 1] * bin[r - l + 1]; } inline int sz(int x){ int ret = 0; for (; x;) ++ret, x /= 10; return ret; } inline bool judge(int l, int m, int r){ if ((r - l + 1) % m) return 0; int t1 = (r - l + 1) / m; LL t = gethash(l, l + t1 - 1); for (int i = l; i <= r; i += t1) if (gethash(i, i + t1 - 1) != t) return 0; return 1; } int main(){ scanf("%s", s + 1); n = strlen(s + 1); Hashtable(); rep(i, 1, n){ rep(j, 1, n){ if (j - i + 1 <= n){ int l = j, r = i + j - 1; f[l][r] = r - l + 1; rep(k, 1, i){ f[l][r] = min(f[l][r], f[l][l + k - 1] + f[l + k][r]); if (judge(l, k, r)) f[l][r] = min(f[l][r], 2 + sz(k) + f[l][l + (r - l + 1) / k - 1]); } } } } printf("%d\n", f[1][n]); return 0; }
标签:ble hashtable logs bzoj eth base 其他 pre can
原文地址:http://www.cnblogs.com/cxhscst2/p/7271485.html