728x90
문제 : algospot.com :: PI
algospot.com :: PI
원주율 외우기 문제 정보 문제 (주의: 이 문제는 TopCoder 의 번역 문제입니다.) 가끔 TV 에 보면 원주율을 몇만 자리까지 줄줄 외우는 신동들이 등장하곤 합니다. 이들이 이 수를 외우기 위해 사용
www.algospot.com
풀이과정
1. 조각의 길이가 3,4,5로 나뉘어질 수 있기 때문에, 난이도가 가장 낮은 경우의 수는
※ 길이가 3인 조각의 난이도 + 3글자를 제외한 나머지 수열에 대한 최소난이도
※ 길이가 4인 조각의 난이도 + 4글자를 제외한 나머지 수열에 대한 최소난이도
※ 길이가 5인 조각의 난이도 + 5글자를 제외한 나머지 수열에 대한 최소난이도
이렇게 3가지 경우가 있기 때문에 for문은 최대 3번씩 돌아가게 된다.
2. 난이도 조건에 맞게 값을 리턴해주는 함수를 따로 만들어서 점화식에 추가해주면,
점화식은 L=3,4,5일때 {start~start+L-1에 대한 난이도} + {start+L에서 시작하는 최소 난이도}
이렇게 정할 수 있다.
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#define INF 987654321
using namespace std;
int C,piSize;
int pi[10001];
int cache[10001];
int calculate(int s, int e) {
int complete = true;
// 모든 숫자가 같은지 체크
for(int i=s; i<e; i++) {
if(pi[i] != pi[i+1]) {
complete = false;
break;
}
}
if(complete) return 1;
complete = true;
// 등차수열인지 체크
for(int i=s; i<e-1; i++) {
if(pi[i] - pi[i+1] != pi[i+1] - pi[i+2]) {
complete = false;
break;
}
}
if(complete && (pi[s] - pi[s+1] == 1 || pi[s+1] - pi[s] == 1))
return 2;
else if(complete)
return 5;
complete = true;
// 번갈아가면서 나타나는지 체크
int prev = pi[s];
int next = pi[s+1];
for(int i=s; i<=e; i+=2) {
if(prev != pi[i]) {
complete = false;
break;
}
}
if(complete == false) return 10;
for(int i=s+1; i<=e; i+=2) {
if(next != pi[i]) {
complete = false;
break;
}
}
if(complete == false) return 10;
return 4;
}
int memorize(int start) {
// 기저사례 : 끝에 도달
if(start == piSize) return 0;
int &ret = cache[start];
if(ret != -1) return ret;
ret = INF;
for(int L=3; L<=5; L++) {
if(start+L <= piSize) {
// 점화식 : {start~start+L까지 난이도} + {start+L 이후부터의 최소난이도}
ret = min(ret, calculate(start,start+L-1)+memorize(start+L));
}
}
return ret;
}
int main()
{
string s;
scanf("%d",&C);
for(int c=0; c<C; c++) {
memset(cache,-1,sizeof(cache));
cin >> s;
piSize = s.size();
for(int i=0; i<s.size(); i++) {
pi[i] = s[i]-48;
}
printf("%d\n",memorize(0));
}
}728x90
'algorithm' 카테고리의 다른 글
| c++) 두니발 박사의 탈옥 (dp) (0) | 2021.07.18 |
|---|---|
| c++) 8장 quantization (dp) (0) | 2021.07.15 |
| c++) 백준 1890-점프 (dp, 재귀함수) (0) | 2021.07.09 |
| c++) 7장 - 울타리 잘라내기 (분할 정복) (0) | 2021.07.08 |
| c++) 백준 10974-모든순열 (0) | 2021.07.05 |