比赛 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;
}