Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Archives
Today
Total
관리 메뉴

pizzaroot

17564번: Dishonest Driver 본문

공부/알고리즘

17564번: Dishonest Driver

pizzaroot 2022. 10. 6. 21:51

\(\mathrm{dp[}i\mathrm{][}j\mathrm{]}\)는 구간 \((i, j]\)의 문자열에 대한 답과 그 문자열을 최대 몇개의 동일한 부분 문자열로 분할할 수 있는지를 저장한다.

 

\(\mathrm{dp[}i\mathrm{][}i\mathrm{]=1}\)

 

\(\displaystyle\mathrm{dp[}i\mathrm{][}j\mathrm{]}=\min_{k=i+1}^{j-1}\mathrm{(dp[}i\mathrm{][}k\mathrm{]}+(0\:\mathrm{or}\:\mathrm{dp[}k\mathrm{][}j\mathrm{]))}\)

 

구간 \((i, k]\)문자열과 \((k, j]\)문자열의 반복된 부분이 같다면 \(\mathrm{0}\)

그렇지 않으면 \(\mathrm{dp[}k\mathrm{][}j\mathrm{]}\)를 취한다.

 

위 부분을 효율적으로 하기 위해서 모든 부분 문자열은 미리 정수 id로 매핑한 후, 새로운 공간에 각 부분문자열의 id를 저장했다. \(O(n^3)\)

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pi;
pi dp[701][701];
bool v[701][701];
int t[701][701];
int n; string s;
map<string, int> mp;
pi solve(int i, int j) {
    if (v[i][j] > 0) return dp[i][j];
    if (i + 1 == j) {
        dp[i][j] = {1, 1};
        v[i][j] = true;
        return dp[i][j];
    }
    int ans = INT_MAX;
    int rep = 1;
    for (int idx = i + 1; idx < j; idx++) {
        pi first = solve(i, idx), second = solve(idx, j);
        if (t[i + 1][(idx - i) / first.second] == t[idx + 1][(j - idx) / second.second]) ans = min(ans, first.first), rep = first.second + second.second;
        else ans = min(ans, first.first + second.first);
    }
    dp[i][j] = {ans, rep};
    v[i][j] = true;
    return dp[i][j];
}
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> s; s = " " + s;
    int idx = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = i; j <= n; j++) mp[s.substr(i, j - i + 1)] = idx++;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = i; j <= n; j++) t[i][j - i + 1] = mp[s.substr(i, j - i + 1)];
    }
    cout << solve(0, n).first << "\n";
    return 0;
}

'공부 > 알고리즘' 카테고리의 다른 글

[2022.11.06. 팀연습] ICPC Seoul Regional 2020 본선 후기  (0) 2022.11.06
ICPC Seoul Regional 2022 예선 후기  (0) 2022.10.11
23338번: Eatcoin  (1) 2022.10.06
23239번: 당근 밭  (0) 2022.10.06
17555번: Blurred Pictures  (0) 2022.10.06
Comments