💡 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)); }