scores = [int(input()) for _ in range(int(input()))]
# zero : highest score when the one does not choice the last wine
# one : highest score when the one choice the last wine, but not the previous one
# two : highest score when the one choice the last wine and the previous one
# define initial conditions
zero, one, two = 0, scores[0], 0
# starting from index 1, iterate through last wine
for score in scores[1:]:
zero, one, two = max(zero, one, two), zero + score, one + score
print(max(zero, one, two))
n가지 가치가 다른 종류의 동전이 있다. 가치의 합이 k원이 되면서 동전의 개수가 최소가 되는 경우를 찾는 문제이다.
동전의 개수의 최솟값을 출력하고 불가능하면 -1을 출력한다.
Idea
dp[k] : k원을 만드는데 필요한 최소 동전 수
dp[k]는 k보다 작은 dp값들로부터 구해질 수 있어서, k 값이 1일때부터 k일때까지 차례로 올라가면 된다.
Pseudocode
for i : 1 ~ k
dp[i] = 1 +
min(
dp[i - value] ( i > value )
0 ( i = value )
inf ( i < value )
for value in values)
i = value 일때 0값을 갖는 이유는 결국 1을 더해주어 dp[i] 값이 1이 되게 하기 위함이다.
Code
def solve(k, dp, values):
for i in range(1, k+1):
dp[i] = min([case(i, dp, value) for value in values]) + 1
return [dp[k], -1][dp[k] == 10000]
def case(i, dp, value):
if i > value:
return dp[i - value]
elif i == value:
return 0
else:
return 10000
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 = [10000] * (k+1)
#answer
print(solve(k, dp, values))
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))
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))
n번째 계단으로 오를 수 있는 경우는 n-1번째 계단에서 한 계단 오르거나, n-2번째 계단에서 두 계단 오르는 경우 뿐이다.
n번째 계단으로 한 계단 올라와서 얻는 최고 점수들을 dp1에.
n번째 계단으로 두 계단 올라와서 얻는 최고 점수들을 dp2에.
구하는 답은 max(dp1[n], dp2[n]).
Base case를 생각해 보면,
dp1[0] = dp2[0] = 0
dp1[1] = scores[1], dp2[1] = 0 (첫 번째 계단으로 두 계단 올라올 수 없음)
dp1[2] = scores[1] + scores[2], dp2[2] = scores[2]
Code
def maxScoreFinalOneStep(n, dp1, dp2, scores):
''' computes max score when the one gets to nth step with final one-up-step '''
#
#base cases
#
#0th step : score 0
if n == 0 and dp1[n] == -1:
dp1[n] = 0
return dp1[n]
#1st step : score[1]
elif n == 1 and dp1[n] == -1:
dp1[n] = scores[n]
return dp1[n]
#2nd step : score[1] + score[2]
elif n == 2 and dp1[n] == -1:
dp1[n] = scores[n-1] + scores[n]
return dp1[n]
#dp2[n-1] not set, compute it
if dp2[n-1] == -1:
dp2[n-1] = maxScoreFinalTwoStep(n-1, dp1, dp2, scores)
#finally fill in dp1[n] and return it
dp1[n] = dp2[n-1] + scores[n]
return dp1[n]
def maxScoreFinalTwoStep(n, dp1, dp2, scores):
''' computes max score when the one gets to nth step with final two-up-step '''
#
#base cases
#
#0th step : score 0
if n == 0 and dp2[n] == -1:
dp2[n] = 0
return dp2[n]
#1st step : score 0. we cannot reach 1st step with final two-up-step
elif n == 1 and dp2[n] == -1:
dp2[n] = 0
return dp2[n]
#2nd step : scores[2]
elif n == 2 and dp2[n] == -1:
dp2[n] = scores[n]
return dp2[n]
#if dp1[n-2] or dp2[n-2] not set, fill them in
if dp1[n-2] == -1:
maxScoreFinalOneStep(n-2, dp1, dp2, scores)
if dp2[n-2] == -1:
maxScoreFinalTwoStep(n-2, dp1, dp2, scores)
#finally fill in dp2[n] and return it
dp2[n] = max(dp1[n-2], dp2[n-2]) + scores[n]
return dp2[n]
if __name__ == '__main__':
#total number of steps
N = int(input())
#scores of each steps. 0th step has 0 score!
scores = [0] + [int(input()) for _ in range(N)]
#dp1[n] : max score when reaches nth step with final one-up-step
dp1 = [-1] * (N+1)
#dp2[n] : max score when reaches nth step with final two-up-step
dp2 = [-1] * (N+1)
#answer
print(max(maxScoreFinalOneStep(N, dp1, dp2, scores), maxScoreFinalTwoStep(N, dp1, dp2, scores)))