반응형

파이썬 / BOJ 백준 / 10844번 쉬운 계단 수 - dp

 

https://www.acmicpc.net/problem/10844

 

10844번: 쉬운 계단 수

첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.

www.acmicpc.net

 

문제

45656이란 수를 보자.
이 수는 인접한 모든 자리수의 차이가 1이 난다. 이런 수를 계단 수라고 한다.
세준이는 수의 길이가 N인 계단 수가 몇 개 있는지 궁금해졌다.
N
이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구하는 프로그램을 작성하시오. (0으로 시작하는 수는 없다.)

 

풀이

wjs

1. DP(동적계획법)을 이용해 풀 수 있는 문제입니다. DP테이블은 이차원 리스트이며 DP[자리 수][앞에 오는 숫자]=경우의 로 표현합니다.

 

2. 앞에 오는 숫자 = 0이면 아래와 같은 식으로 표현합니다. 0 다음에는 1밖에 올 수 없습니다. 

DP[자리 수][0] = DP[자리 수 - 1][1]

맨앞에는 0올수 없고, 그 아래 자리수부터는 0이 올 수 있으니, 맞교환하는 식으로 하여, 간단하게 식을 만듭니다.

 

 3. 앞에 오는 숫자 = 1~8 이면 아래와 같은 식으로 표현합니다. 1 ~ 8은 각각 2개씩 올 수 있습니다. 

DP[자리 수][앞에 오는 숫자] = DP[자리 수 - 1][앞에 오는 숫자 -1] + DP[자리 수 - 1][앞에 오는 숫자 + 1]

 

 4. 앞에 오는 숫자 = 9이면 아래와 같은 식으로 표현합니다.

DP[자리 수][9] = DP[자리 수 - 1][8]

 

5. 마지막에 DP[자리수]에 있는 값을 모두 더하고, 1000000000의 나머지를 구해줍니다.

 

전체 코드

n = int(input())
dp = [[0 for i in range(10)] for j in range(101)]
for i in range(1, 10):
    dp[1][i] = 1
for i in range(2, n + 1):
    for j in range(10):
        if j == 0:
            dp[i][j] = dp[i - 1][1]
        elif j == 9:
            dp[i][j] = dp[i - 1][8]
        else:
            dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j + 1]
    #print(dp[i])
print(sum(dp[n]) % 1000000000)
반응형
반응형

파이썬 / BOJ 백준 / 1932번 정수 삼각형 - dp

https://www.acmicpc.net/problem/1932

 

1932번: 정수 삼각형

첫째 줄에 삼각형의 크기 n(1 ≤ n ≤ 500)이 주어지고, 둘째 줄부터 n+1번째 줄까지 정수 삼각형이 주어진다.

www.acmicpc.net

문제

위 그림은 크기가 5인 정수 삼각형의 한 모습이다.

맨 위층 7부터 시작해서 아래에 있는 수 중 하나를 선택하여 아래층으로 내려올 때, 이제까지 선택된 수의 합이 최대가 되는 경로를 구하는 프로그램을 작성하라. 아래층에 있는 수는 현재 층에서 선택된 수의 대각선 왼쪽 또는 대각선 오른쪽에 있는 것 중에서만 선택할 수 있다.

삼각형의 크기는 1 이상 500 이하이다. 삼각형을 이루고 있는 각 수는 모두 정수이며, 범위는 0 이상 9999 이하이다.

 

풀이

1. dp 수 있는 문제입니다.
2.
위 층의 값들을 아래층의 값에 합산해 갈 수 있는데, 합산하는데 3가지 case가 있습니다.
3.
첫번째 케이스는 j = 0일 경우 아래층의 값은 바로 위층의 값을 가져와 합산합니다.
dp[i][j] + dp[i - 1][j]
4.
두번째 케이스는 i = j일 경우 아래층의 값은 왼쪽 대각선 위층의 값을 가져와 합산합니다.
dp[i][j] = dp[i][j] + dp[i - 1][j - 1]
5.
세번째 케이스는 나머지 조건일 경우 아래층의 값은 바로 위층의 값과 왼쪽 대각선 위층의 값중 큰 값을 가져와 합산합니다.
dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j]) + dp[i][j]

6. 마지막으로 맨 아래층의 값 중 가장 큰값을 출력합니다.

 

전체코드

n = int(input())
dp = []
for i in range(n):
    dp.append(list(map(int, input().split())))
k = 2
for i in range(1, n):
    for j in range(k):
        if j == 0:
            dp[i][j] = dp[i][j] + dp[i - 1][j]
        elif i == j:
            dp[i][j] = dp[i][j] + dp[i - 1][j - 1]
        else:
            dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j]) + dp[i][j]
    k += 1
print(max(dp[n - 1]))
반응형

+ Recent posts