BOJ 2135 - 문자열 압축하기

image.png

$O(n^3)$ DP로 풀 수 있다.

$dp[l][r]$ 을 $l \sim r$ 문자열에서 최소 길이라고 하자.

transition은

  • $l \sim r$ 구간을 두 부분으로 쪼개는 것
  • $l$부터 시작하는 반복되는 문자열로 묶는 것

두 가지를 검사해주면 된다.

string s;
int n, dp[201][201];
string sub[201][201];

int fn(int l, int r) {
   if (l == r) return 1;
   if (l > r) return 0;
   int &ret = dp[l][r];
   if (~ret) return ret;
   ret = r - l + 1;

   for (int i = l; i <= r - 1; i++) {
      mina(ret, fn(l, i) + fn(i + 1, r));
   }

   for (int len = 1; len * 2 <= r - l + 1; len++) {
      int same = 1;
      for (int c = l + len; c + len - 1 <= r; c += len) {
         if (sub[l][l + len - 1] == sub[c][c + len - 1]) same++;
         else break;
      }
      if (same > 1) {
         mina(ret, sz(to_string(same)) + 2 + fn(l, l + len - 1) + fn(l + len * same, r));
      }
   }

   return ret;
}

void solve() {
   memset(dp, -1, sizeof dp);
   cin >> s;
   n = sz(s);
   for (int i = 0; i < n; i++) for (int j = i; j < n; j++) sub[i][j] = s.substr(i, j - i + 1);
   cout << fn(0, n - 1);
}

Tags:

Categories:

Updated:

Comments