다이나믹 프로그래밍 공부를 시작하는 문제이다. 규칙을 찾아 점화식을 만드는 것이 중요했다. 우선 메모라이제이션을 위한 배열 dp를 만들고 dp의 인덱스는 구매하는 카드의 수로 두고 문제를 접근하였다. dp에 몇장의 카드를 살 때의 최대 금액을 저장하여 dp[n]을 결과값으로 내는 방식으로 해결하였다.
카드를 1장 사는 경우인 dp[1]과 p[1]의 합
과 카드를 0장 산 경우인 dp[0]과 p[2]의 합
중 큰 값을 취한다.카드를 2장 사는 경우인 dp[2]과 p[1]의 합
과 카드를 1장 사는 경우인 dp[1]와 p[2]의 합
과 카드를 0장 사는 경우인 dp[0]과 p[3]의 합
중 큰 값을 취한다.이러한 과정을 식으로 나타낸다면 다음과 같이 나타낼 수 있다.
for i in range(1, n+1):
for j in range(1, i+1):
if dp[i]<dp[i-j]+p[j]:
dp[i]=dp[i-j]+p[j]
dp에 각 카드 수 별 최대 금액을 저장하고 더 많은 카드를 살 때에 dp에 저장된 수를 그대로 사용하여 연산의 크기를 줄이게 된다.
n=int(input())
p=[0]+list(map(int, input().split()))
dp=[0]*(n+1)
dp[1]=p[1]
for i in range(2, n+1):
for j in range(1, i+1):
if dp[i]<dp[i-j]+p[j]:
dp[i]=dp[i-j]+p[j]
print(dp[n])