백준_1463_1로 만들기(동적계획법)

맹민재·2022년 10월 19일
0

알고리즘

목록 보기
7/134

처음 생각한 풀이

우선 1~3까지는 횟수가 1번으로 정해져 있으므로 1로 dp 배열에 넣고 4부터 2로 나누어지면 2로 나눈 숫자의 횟수에 1을 더하고 3으로 나누어지면 3으로 나눈 숫자의 횟수에 1을 더한다 2, 3 둘다 나눠 지지 않으면 이전 숫자의 횟수에 1을 더하는 방식으로 한다.

n = int(input())

dp = [0, 0, 1, 1]

for i in range(4, n+1):
    if i % 3 == 0:
        dp.append(dp[i//3]+1)
    elif i % 2 == 0:
        dp.append(dp[i//2]+1)
    else:
        dp.append(dp[i-1]+1)
print(dp)
print(dp[n])

실행결과


실행결과를 확인했을 때 2,3으로 나누어지더라도 이전 숫자의 횟수가 적으면 이전 숫자에서 1을 더하는 방식이 적을 수 있으므로 이전 숫자나 나누어 졌을 때의 횟수 비교가 필요하다는 것을 깨달음


수정 코드

n = int(input())

dp = [0, 0, 1, 1]

for i in range(4, n+1):
    if i % 3 == 0:
        dp.append(min(dp[i//3], dp[i-1]) + 1)
    elif i % 2 == 0:
        dp.append(min(dp[i//2], dp[i-1]) + 1)
    else:
        dp.append(dp[i-1]+1)
print(dp)
print(dp[n])

여러 테스트 결과 정답처럼 보여서 제출했지만 백준에서는 틀렸다고 한다.
생각해 봤을 때 2와 3의 최소 공배수 즉 6으로 나누어 떨여질때는 2와 3중 어떤 것으로 나눌때가 최소인지 구분하는것도 필요하다고 생각

수정 코드

n = int(input())

dp = [0, 0, 1, 1]

for i in range(4, n+1):
    if i % 6 == 0:
        dp.append(min(dp[i//3], dp[i//2], dp[i-1]) + 1)
    elif i % 3 == 0:
        dp.append(min(dp[i//3], dp[i-1]) + 1)
    elif i % 2 == 0:
        dp.append(min(dp[i//2], dp[i-1]) + 1)
    else:
        dp.append(dp[i-1]+1)

print(dp[n])

드디어 정답


다른사람 코드와 비교

n = int(input())
d = [0] * 1000001

for i in range(2, n+1):
    d[i] = d[i-1] + 1
    
    if i % 2 == 0:
        d[i] = min(d[i], d[i//2] + 1)

    if i % 3 == 0:
        d[i] = min(d[i], d[i//3] + 1)

print(d[n])

해당 인덱스를 이전 인덱스에서 1을 더한 값을 먼저 지정한 후 if ~elif가 아닌 if문으로 2, 3으로 나눠지는 경우를 설정 했기 때문에 6으로 나눠지는 경우도 따로 작성할 필요 없다.... 한 수 배웠습니다

profile
ㄱH ㅂrㄹ ㅈr

0개의 댓글