UVA1630 Folding(区间 dp)

Description

求一个字符串 S S S 的最短可嵌套压缩的方案。如 AAAAAAAAAABABABCCD 最短为 9(A)3(AB)CCD

1 ≤ ∣ S ∣ ≤ 100 1 \leq |S| \leq 100 1S100

Solution

对于一个字符串,令 f i , j f_{i,j} fi,j [ i , j ] [i,j] [i,j] 的最短压缩长度,有三个压缩。

  1. 原串形式,将 f i , j f_{i,j} fi,j 赋初值为 j − i + 1 j-i+1 ji+1
  2. 拼接形式,枚举拼接点 k k k f i , j = min ⁡ { f i , j , f i , k + f k + 1 , j } f_{i,j} = \min \{f_{i,j}, f_{i,k} + f_{k + 1, j} \} fi,j=min{fi,j,fi,k+fk+1,j}
  3. 嵌套形式,枚举嵌套的周期长度,若能嵌套,则转移,与重复次数的位数 + 2 + 2 +2 即两个括号 + + + 周期长度取 min。

因为字符串长度只有一百,所以 f 数组为 string 类型,也就 1 0 6 10^6 106。不过在枚举顺序上我遇到了一个问题,如果我们按正常顺序枚举 i i i j j j,那么在枚举 k k k 进行拼接转移时, f k + 1 , j f_{k+1,j} fk+1,j 是没有处理过的。可以发现, f i , j f_{i,j} fi,j 中的 j j j 是固定的,所以可以第一维枚举 j j j,第二维枚举 i i i

Code

#include <bits/stdc++.h>
using namespace std;
const int N = 100 + 5;
int n;
string f[N][N];
char s[N];
int count(int x) {
	int ans = 0;
	while (x) ans++, x /= 10;
	return ans;
}
string get (int l, int r) {
	string ans = "";
	for (int i = l; i <= r; i++) ans += s[i];
	return ans;
}
string tostr(int x) {
	string ans;
	while (x) ans += (x % 10) + '0', x /= 10;
	reverse(ans.begin(), ans.end());
	return ans; 
}
int main() {
	while (~scanf("%s", s + 1)) {
		n = strlen(s + 1); 
		for (int i = 1; i <= n; i++) 
			for (int j = 1; j <= n; j++) {
				if (i == j) f[i][i] = s[i];
				else f[i][j] = "";
			}
		for (int j = 1; j <= n; j++)
  	    	for (int i = j - 1; i >= 1; i--) {
				f[i][j] = get(i, j);
				for (int k = i; k < j; k++) 
					if (f[i][j].size() > f[i][k].size() + f[k + 1][j].size()) f[i][j] = f[i][k] + f[k + 1][j];
				for (int k = i; k < j; k++) {
					if (s[k] == s[j] && (j - i + 1) % (k - i + 1) == 0) {
						string tmp = get(i, k);
						int p = k;
						while (p < j && s[p + 1] == tmp[(p - i + 1) % (k - i + 1)]) p++;
						if (p == j) {
							if (f[i][j].size() > f[i][k].size() + count((j - i + 1) / (k - i + 1)) + 2) {
								f[i][j] = tostr((j - i + 1) / (k - i + 1)) + "(" + f[i][k] + ")";
							}
						}
					}
				}	
			}
 		printf("%s\n", f[1][n].c_str());
	}
	return 0;
} 
posted @ 2020-02-20 11:13  ylxmf2005  阅读(24)  评论(0)    收藏  举报