1로 만들기
디피로 완전탐색하자.
덜 논리적이라 디피는 재귀로 풀곤하는데(2)(완전 거의 대부분) 포문풀이(1)와 속도 차이가 4배정도 난다.
또한 재귀적으로 나누기 3의 상태를 보는게(3) 더 빠르다. 아마 더 빨리 1에 가까워져서가 아닐까 싶다
(1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <stdio.h> int dp[1000001]; int main() { int n, i; scanf("%d", &n); dp[1] = 0, dp[2] = 1, dp[3] = 1; for (i = 4; i <= n; i++) { dp[i] = dp[i - 1] + 1; if (i % 2 == 0 && dp[i / 2] + 1 < dp[i]) dp[i] = dp[i / 2] + 1; if (i % 3 == 0 && dp[i / 3] + 1 < dp[i]) dp[i] = dp[i / 3] + 1; } printf("%d", dp[n]); } | cs |
(2)
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 35 36 37 38 39 | #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define fail 987654321 int n, dp[1000001]; int func(int x) { if (x < 1) return fail; if (x == 1) return 0; int& ref = dp[x]; if (ref != -1) return ref; int a = fail, b = fail, c = fail; if (x % 3 == 0) a = func(x / 3) + 1; if (x % 2 == 0) b = func(x / 2) + 1; c = func(x - 1) + 1; return ref = min(min(a, b), c); } int main() { scanf("%d", &n); memset(dp, -1, sizeof(dp)); printf("%d", func(n)); return 0; } | cs |
(3)
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 35 36 37 38 39 | #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define fail 987654321 int n, dp[1000001]; int func(int x) { if (x < 1) return fail; if (x == 1) return 0; int& ref = dp[x]; if (ref != -1) return ref; int a = fail, b = fail, c = fail; c = func(x - 1) + 1; if (x % 2 == 0) b = func(x / 2) + 1; if (x % 3 == 0) a = func(x / 3) + 1; return ref = min(min(a, b), c); } int main() { scanf("%d", &n); memset(dp, -1, sizeof(dp)); printf("%d", func(n)); return 0; } | cs |
'알고리즘 > Dynamic Programming 동적계획법' 카테고리의 다른 글
백준) 2965 캥거루 세마리 (0) | 2018.02.06 |
---|---|
백준) 2156 포도주 시식 (0) | 2018.02.04 |
백준) 2579 계단 오르기 (0) | 2018.02.02 |
백준) 1149 RGB거리 (0) | 2018.02.01 |
백준) 2342 Dance Dance Revolution (0) | 2017.09.21 |