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

Description

아래와 같은 숫자 삼각형이 주어질 때, 맨 위에서 아래로 이동하는 경로 중 숫자의 합이 제일 큰 경로를 찾는 문제.

7

3    8

8    1    0

2    7    4    4

4    5    2    6    5

층 수 n 과 각 층의 숫자가 주어진다. 최댓값을 구하면 된다.

Idea

2차원 list로 하면 index 처리가 간단해지지만 memory overhead가 크다. 1차원 list로 풀어보자.

총 [latex]n(n+1)/2[/latex]개의 숫자가 존재하므로,

dp <- [-1] * n(n+1)/2로 초기화한다.

각 층의 숫자는 triangle이라는 list에 저장한다.

Pseudocode

for i: 0~n-1

for j:0~i

ind = i(i+1)/2 + j

dp[ind] =

  1. dp[i(i-1)/2] + triangle[ind]  ( j = 0 )
  2. dp[i(i-1)/2 + j - 1] + triangle[ind] ( j = i )
  3. max(dp[i(i-1)/2 + j - 1], dp[i(i-1)/2 + j]) + triangle[ind] ( j = 나머지 )
답은 max(dp[n(n-1)/2 + 0, 1, 2 ...., n]).

Code

def solve(triangle, dp, n):
    solveHelper(triangle, dp, n)
    return max([dp[n*(n-1)//2 + j] for j in range(n)])

def solveHelper(triangle, dp, n):
    dp[0] = triangle[0]

    for i in range(1, n):
        for j in range(i+1):
            ind = i*(i+1)//2 + j
            # case 1 : leftmost number of a row
            if j == 0:
                dp[ind] = dp[i*(i-1)//2] + triangle[ind]
            # case 2: rightmost number of a row
            elif j == i:
                dp[ind] = dp[i*(i-1)//2 + j - 1] + triangle[ind]
            # case 3: middle
            else:
                dp[ind] = max(dp[i*(i-1)//2 + j - 1], dp[i*(i-1)//2 + j]) + triangle[ind]

if __name__ == '__main__':
    n = int(input())

    triangle = []
    for i in range(n):
        triangle += [int(v) for v in input().strip().split()]

    dp = [-1] * (n*(n+1)//2)
    print(solve(triangle, dp, n))

'Programming > Algorithm' 카테고리의 다른 글

[Dynamic Programming] 포도주 시식  (0) 2016.07.05
[Dynamic Programming] 동전 2  (0) 2016.07.05
[String] KMP  (0) 2016.07.05
[Dynamic Programming] 동전 1  (0) 2016.07.05
[Dynamic Programming] 계단 오르기  (0) 2016.07.04
https://www.acmicpc.net/problem/2902

Description

Knuth-Morris-Pratt 과 같이 긴 형식을 KMP 와 같이 짧은 형식으로 바꾸는 문제.

Idea

간단하다. 그냥 대문자만 뽑아내면 된다...

Code

print("".join([c for c in input() if c.isupper()]))

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

Description

n가지 종류의, 가치가 서로 다른 동전이 주어진다. 이 동전들로 총합 k원을 만들고자 할 때 모든 경우의 수를 구하는 문제이다.

Idea

dp : (k * n) 2차원 배열 values: 동전의 가치의 배열 dp[i][j]  : 총합 i원을 만드는데, 가장 큰 가치를 갖는 동전이 values[j]원인 경우의 수 위와 같이 정의하면,
  1. i < values[j] 일때 : dp[i][j] = 0
  2. i =values[j] 일때 : dp[i][j] = 1
  3. i > values[j] 일때 : dp[i][j] = dp[i - j][0] + dp[i - j][1] + ... + dp[i - j][j]
이다.

Code

def solve(k, dp, values):
    #rowwise iteration through dp (it is k * n 2d list!)
    for i in range(k+1):
        for j in range(len(values)):
            #case 1 : i < values[j] -> dp[i][j] = 0
            if i < values[j]:
                dp[i][j] = 0
            #case 2 : i == values[j] -> dp[i][j] = 1
            elif i == values[j]:
                dp[i][j] = 1
            #case 3 : i > values[j] -> dp[i][j] = sum(dp[i-values[j]][0, 1, ..., j])
            else:
                dp[i][j] = sum([dp[i-values[j]][x] for x in range(j+1)])

    return sum([dp[k][x] for x in range(len(values))])


if __name__ == '__main__':
    #parse input
    n, k = [int(i) for i in input().split()]
    values = [int(input()) for _ in range(n)]

    #make dp list
    dp = [[-1] * n for _ in range(k+1)]

    #answer
    print(solve(k, dp, values))

'Programming > Algorithm' 카테고리의 다른 글

[Dynamic Programming] 포도주 시식  (0) 2016.07.05
[Dynamic Programming] 동전 2  (0) 2016.07.05
[Dynamic Programming] 숫자 삼각형  (0) 2016.07.05
[String] KMP  (0) 2016.07.05
[Dynamic Programming] 계단 오르기  (0) 2016.07.04

+ Recent posts