반응형
#INFO
난이도 : SILVER1
알고리즘 유형 : DP
https://www.acmicpc.net/problem/12852
#SOLVE
DynamicProgramming 방식을 이용해 문제를 풀이했습니다.
dp[i] = i 를 1로 만드는 연산의 최솟값
before[i] = 연산 (1 or 2 or 3) 을 수행하기 직전의 i 값 . ex) before[10] = 9
before 배열은 N을 1로 만드는 방법에 포함되어 있는 수를 출력하기 위해 정의했습니다.
1. X가 3으로 나누어 떨어지면 3으로 나눈다.
before[i] = i - 1;
if (i % 3 == 0 && dp[i] > dp[i/3] + 1) {
dp[i] = dp[i/3] + 1;
before[i] = i / 3;
}
2. X가 2로 나누어 떨어지면 2로 나눈다.
if (i % 2 == 0 && dp[i] > dp[i/2] + 1) {
dp[i] = dp[i/2] + 1;
before[i] = i / 2;
}
3. 1을 뺀다.
dp[i] = dp[i-1] + 1;
before[i] = i - 1;
위의 3가지 식을 비교하며 최소로 연산을 수행하는 값을 dp 배열에 저장한 뒤 n번째 dp값을 출력하면 됩니다.
#CODE
#include <iostream>
using namespace std;
int dp[1000001];
int before[1000001];
int main() {
int n;
cin >> n;
//init
dp[0] = 0;
dp[1] = 0;
before[1] = -1;
//dp
for(int i = 2 ; i <= n ; i++) {
dp[i] = dp[i-1] + 1;
before[i] = i - 1;
if (i % 3 == 0 && dp[i] > dp[i/3] + 1) {
dp[i] = dp[i/3] + 1;
before[i] = i / 3;
}
if (i % 2 == 0 && dp[i] > dp[i/2] + 1) {
dp[i] = dp[i/2] + 1;
before[i] = i / 2;
}
}
cout << dp[n] << endl;
cout << n << " ";
while(before[n] != -1) {
cout << before[n] << " ";
n = before[n];
}
return 0;
}
반응형
'Archive2 > ProblemSolving' 카테고리의 다른 글
[BOJ] C++ 1919 "애너그램 만들기" 문제 풀이 _ nov (0) | 2022.02.24 |
---|---|
[BOJ] C++ 6198 "옥상 꾸미기" 문제 풀이 _ nov (0) | 2022.02.23 |
[BOJ] 2170 "선 긋기" 문제 풀이 & 소스 코드 With C/C++ (0) | 2022.02.15 |
[BOJ] 3986 "좋은 단어" 문제 풀이 & 소스 코드 With C/C++ (0) | 2022.02.11 |
[BOJ] 1018 "체스판 다시 칠하기" 문제 풀이 & 소스 코드 With C/C++ (0) | 2022.02.08 |