比赛 |
EYOI与SBOI开学欢乐赛13th |
评测结果 |
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA |
题目名称 |
折叠字符串(Folding) |
最终得分 |
100 |
用户昵称 |
yrtiop |
运行时间 |
0.000 s |
代码语言 |
C++ |
内存使用 |
0.00 MiB |
提交时间 |
2022-10-21 20:26:55 |
显示代码纯文本
#include <bits/stdc++.h>
const int maxn = 105;
const int p = 131;
char s[maxn];
int dp[maxn][maxn],hash[maxn],pw[maxn],P[maxn][maxn],sum[maxn],w[maxn][maxn];
bool check(int l,int r,int k) {
for(int i = l + k - 1;i <= r;i += k)
if(hash[i] - hash[i - k] * pw[k] != hash[l + k - 1] - hash[l - 1] * pw[k])
return false;
return true;
}
void dfs(int l,int r) {
if(P[l][r] == r) {
if(w[l][r] < r - l + 1) {
printf("%d(",(r - l + 1) / w[l][r]);
dfs(l , l + w[l][r] - 1);
printf(")");
return ;
}
else {
for(int i = l;i <= r;++ i)
printf("%c",s[i]);
return ;
}
return ;
}
dfs(l , P[l][r]);
dfs(P[l][r] + 1 , r);
return ;
}
int main() {
freopen("folding.in","r",stdin);
freopen("folding.out","w",stdout);
scanf("%s",s + 1);
int n = strlen(s + 1);
pw[0] = 1;
for(int i = 1;i <= n;++ i)
hash[i] = hash[i - 1] * p + s[i],pw[i] = pw[i - 1] * p;
for(int i = 1;i <= 9;++ i)sum[i] = 1;
for(int i = 10;i <= 99;++ i)sum[i] = 2;
sum[100] = 3;
for(int i = 1;i <= n;++ i)dp[i][i] = 1,P[i][i] = i,w[i][i] = 1;
for(int len = 2;len <= n;++ len) {
for(int i = 1;i + len - 1 <= n;++ i) {
int j = i + len - 1;
dp[i][j] = len;
P[i][j] = j;
w[i][j] = j;
for(int k = 1;k * k <= len;++ k) {
if(len % k)continue ;
if(check(i , j , k)) {
int val = 2 + sum[len / k] + dp[i][i + k - 1];
if(val < dp[i][j]) {
w[i][j] = k;
dp[i][j] = val;
}
}
if(check(i , j , len / k)) {
int val = 2 + sum[k] + dp[i][i + len / k - 1];
if(val < dp[i][j]) {
w[i][j] = len / k;
dp[i][j] = val;
}
}
}
for(int k = i;k < j;++ k) {
if(dp[i][j] > dp[i][k] + dp[k + 1][j]) {
dp[i][j] = dp[i][k] + dp[k + 1][j];
P[i][j] = k;
}
}
}
}
dfs(1 , n);
return 0;
}