Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
Tags
- 소수
- BOJ
- dynamic programming
- sw expert academy
- hackerrank
- 시뮬레이션
- C++
- SWEA
- 백트래킹
- koitp
- 해커랭크
- PS
- 잠실
- 알고리즘
- 구현
- DP
- 에라토스테네스의 체
- 삼성 SDS 대학생 알고리즘 특강
- 다이나믹 프로그래밍
- BFS
- 삼성 기출
- 완전탐색
- Algorithm
- 맛집
- dfs
- 스택
- 백준
- 그리디
- 동적 계획법
- 브루트포스
Archives
- Today
- Total
펭로그
[C++] BOJ 백준 1463 1로 만들기 본문
문제링크 : https://boj.kr/1463
DP를 사용하면 이전 단계의 계산 결과를 그대로 활용할 수 있는 문제이다.
문제에서 힌트로 주어진 10을 연산하는 방법을 생각해보면
10 -> 5 -> 4 -> 2 -> 1
10 -> 9 -> 3 -> 1
이런 방법이 나올 수 있을 것이다.
10이라는 숫자는 바로 2로 나눌 수 있는 숫자이지만 -1을 한 후에 연산하면 횟수가 더 적은 것을 확인할 수 있다.
따라서, 어떤 숫자가 2나 3으로 나눌 수 있을 지라도 -1을 했을 때와 비교한 후 최소 횟수가 어느쪽인지를 취하면 문제를 풀 수 있게 된다.
1을 뺀 후에 연산하는 방법이 어떤 경우에도 허용이 되기 때문에 먼저 1을 빼서 연산한 횟수를 계산한다.
현재 숫자에서 1을 뺀 연산은 이전 단계에서 이미 연산이 되었기 때문에 dp[i-1]에다가 연산 횟수 1회만 추가하면 된다.
그리고 3으로 나누어지거나 2로 나누어지거나 어떤 연산을 우선적으로 해도 상관은 없다.
그 값은 이미 구해져있기 때문이다.
이 역시 dp[i/3]이나 dp[i/2]에다가 연산 횟수 1회만 추가하면 된다.
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 29 30 31 32 33 34 | // BOJ 1463 1로 만들기 #include <bits/stdc++.h> using namespace std; int min(int a, int b) { return a > b ? b : a; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); // freopen("../input.txt", "r", stdin); int num; cin >> num; vector<int> dp(num + 1); // 초기 기저 값 dp[1] = 0; dp[2] = 1; dp[3] = 1; for (int i = 4; i <= num; i++) { dp[i] = dp[i - 1] + 1; if (i % 3 == 0) dp[i] = min(dp[i], dp[i / 3] + 1); else if (i % 2 == 0) dp[i] = min(dp[i], dp[i / 2] + 1); } cout << dp[num]; return 0; } | cs |
'Study > PS(Algorithm)' 카테고리의 다른 글
[C++] 백준 BOJ 2110 공유기 설치 (실패) (0) | 2018.09.07 |
---|---|
[C++] 백준 BOJ 2293 동전1 (0) | 2018.09.04 |
[C++] BOJ 백준 2193 이친수 (0) | 2018.08.31 |
[C++] 백준 BOJ 14501 퇴사 (0) | 2018.08.29 |
[C++] 백준 BOJ 11052 붕어빵 판매하기 (0) | 2018.08.21 |
Comments