halang-log
💡 PS

[BOJ] 13392 방법을 출력하지 않는 숫자 맞추기

date
Feb 16, 2022
slug
boj-13392
author
status
Public
tags
PS
DP
summary
방법을 출력하지 않는 숫자 맞추기 문제에 대한 풀이입니다.
type
Post
thumbnail
category
💡 PS
updatedAt
Aug 3, 2023 08:53 AM
언어

문제

풀이

dp문제이다. 나는 상태공간을 dp[ix][cnt] = 현재 나사 번호 ix를 보고 있고 왼쪽 회전 수가 cnt일 때 최소 회전수로 설정했다. 숫자 나사 1부터 왼쪽으로 돌릴지 오른쪽으로 돌릴지를 정해준다. 왼쪽 회전수 같은 경우 아래에 있는 나사들에 영향을 미치기 때문에 저장해두어야 한다.
처음에는 왼쪽 회전 수 크기를 10001로 잡았는데 메모리 초과가 떴다. 생각해보면, 왼쪽 회전 수(cnt)는 항상 10미만으로 줄일 수 있다. 왜냐하면 왼쪽 회전 수가 10번일 때와 0번일 때의 상태가 같기 때문이다.
코드에 대해 추가 설명을 하겠다.
int st = int(s[ix] - '0') + cnt : st는 나사 번호 ix의 정면에 있던 숫자 + 왼쪽 회전 수이다. 이는 10이 넘어갈 수 있으므로 그 다음줄에서 st %= 10;를 해주어 st를 0부터 9사이의 수로 맞추어 주었다.
ret = min(ret, go(ix + 1, (cnt + tmp)%10) + tmp); : 여기서 cnt 자리는 10미만인 수가 와야 하므로 %연산자를 사용하고 값을 넘겨준다.

코드

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n; string s, e; int dp[10000][10]; int go(int ix, int cnt) { if (ix == n) return 0; if (dp[ix][cnt] != -1) return dp[ix][cnt]; // 오른쪽 회전 int st = int(s[ix] - '0') + cnt, fi = int(e[ix] - '0'), tmp = 0, ret; st %= 10; if (fi > st) tmp = st + 10 - fi; else if (fi < st) tmp = st - fi; ret = go(ix + 1, cnt) + tmp; // 왼쪽 회전 st = int(s[ix] - '0') + cnt, fi = int(e[ix] - '0'), tmp = 0; st %= 10; if (fi > st) tmp = fi - st; else if (fi < st) tmp = 10 - st + fi; ret = min(ret, go(ix + 1, (cnt + tmp)%10) + tmp); return dp[ix][cnt] = ret; } int main() { memset(dp, -1, sizeof(dp)); scanf("%d", &n); cin >> s >> e; printf("%d", go(0, 0)); }