728x90
개요
문제 링크
골드 5, DP
연속된 부분 문자열의 최소 구성 횟수
접근
접근 자체는 매우 쉽지만 구현이 까다로워서 실수하기 좋음
길이 L이 100으로 작으므로 O(L×L×N) 수준에서 해결가능, N은 크므로 루프는 한 번만 돌려야하고, 루프를 돌 때 중심이 처음 문자열이 됨을 알 수 있음.
문자열 루프를 돌면서 n개의 component 중 같은 것을 찾고, 만약 같다면 component의 길이만큼 뺀 위치의 값과 비교
dp[i-component_length]+1과 dp[i] 비교해서 최솟값으로 업데이트
이때 마지막 출력 조건이 앞에서부터 component를 출력하는 것이므로 업데이트마다 앞이 어딘지, 어떤 component를 사용했는지 같이 업데이트 해야함.
// 아래와 같다면 ...1234.... 23 // (3이 있는 위치의 길이)는 (1이 있는 위치의 길이)부터 // 하나(23)만 추가해서 구성 가능함 // // 따라서 (1이 있는 위치의 길이)+1과 비교 후 // (길이, 앞=1이 있는 위치, 어떤=component(23)의 인덱스)를 업데이트
Pseudo code
for (i)
for (j = i의 앞)
for (component)
// 1. component의 길이만큼 앞의 위치를 찾고
if (component의 길이와 i-j가 다르면)
continue
// 2. 길이뿐 아니라 문자열도 동일한지 확인하고
if (component와 j~i substring이 다르면)
continue
// 3. 더 크면 업데이트할 필요가 없으므로
if (앞의 위치의 최대 길이 + 1이 현재 저장된 값보다 크면)
continue
dp[i].length = dp[j].length+1 // 길이
dp[i].previous = j // 앞
dp[i].component_index = index(component) // 어떤
Source code
#include <bits/stdc++.h>
using namespace std;
int dp[110][3];
int val[] = {2,2,2,3,3,3,4,4,1,1,5,5,6,6,0,7,0,7,7,8,8,8,9,9,9,0};
int compare(string a, string b) {
for (int i=0; i<a.size(); i++)
if (val[a[i]-'a']+'0' != b[i])
return 1;
return 0;
}
int main() {
string a, s;
int n;
vector <string> p, q;
cin >> a >> n;
int m = a.size();
for (int i=0; i<n; i++) {
cin >> s;
q.push_back(s);
}
for (int i=1; i<=m; i++) {
dp[i][0] = 2e9;
for (int j=0; j<i; j++) {
for (int k=0; k<n; k++) {
string x = q[k];
if (x.size() != i-j)
continue;
if (compare(x, a.substr(j, i-j)))
continue;
if (dp[j][0]+1 >= dp[i][0])
continue;
dp[i][0] = dp[j][0]+1;
dp[i][1] = j;
dp[i][2] = k;
}
}
}
int v = dp[m][0];
if (v == 2e9) {
cout << "0\nNo solution.";
return 0;
}
cout << v << '\n';
for (int i=0; i<v; i++) {
p.push_back(q[dp[m][2]]);
m = dp[m][1];
}
for (int i=0; i<v; i++)
cout << p[v-i-1] << "\n";
}
728x90
'백준브실골 > DP' 카테고리의 다른 글
백준 24430, 알고리즘 수업 - 행렬 경로 문제 7 (0) | 2023.02.08 |
---|---|
백준 1943, 동전 분배 (0) | 2023.02.08 |
백준 2218, 상자 안의 구슬 (0) | 2023.02.08 |
백준 2228, 구간 나누기 (0) | 2023.02.08 |
백준 12887, 경로 게임 (0) | 2023.02.08 |
백준 1577, 도로의 개수 (0) | 2023.02.08 |
백준 25633, 도미노 넘어뜨리기 (0) | 2023.02.08 |
백준 21600, 계단 (0) | 2023.02.08 |
댓글