1 λΆ„ μ†Œμš”

λ°±μ€€ μ‚¬μ΄νŠΈ 링크

문제

n개의 μ •μˆ˜λ‘œ 이루어진 μž„μ˜μ˜ μˆ˜μ—΄μ΄ μ£Όμ–΄μ§„λ‹€. μš°λ¦¬λŠ” 이 쀑 μ—°μ†λœ λͺ‡ 개의 수λ₯Ό μ„ νƒν•΄μ„œ ꡬ할 수 μžˆλŠ” ν•© 쀑 κ°€μž₯ 큰 합을 κ΅¬ν•˜λ €κ³  ν•œλ‹€. 단, μˆ˜λŠ” ν•œ 개 이상 선택해야 ν•œλ‹€.

예λ₯Ό λ“€μ–΄μ„œ 10, -4, 3, 1, 5, 6, -35, 12, 21, -1 μ΄λΌλŠ” μˆ˜μ—΄μ΄ μ£Όμ–΄μ‘Œλ‹€κ³  ν•˜μž. μ—¬κΈ°μ„œ 정닡은 12+21인 33이 정닡이 λœλ‹€.

μž…λ ₯

첫째 쀄에 μ •μˆ˜ n(1 ≀ n ≀ 100,000)이 μ£Όμ–΄μ§€κ³  λ‘˜μ§Έ μ€„μ—λŠ” n개의 μ •μˆ˜λ‘œ 이루어진 μˆ˜μ—΄μ΄ μ£Όμ–΄μ§„λ‹€. μˆ˜λŠ” -1,000보닀 ν¬κ±°λ‚˜ κ°™κ³ , 1,000보닀 μž‘κ±°λ‚˜ 같은 μ •μˆ˜μ΄λ‹€.

좜λ ₯

첫째 쀄에 닡을 좜λ ₯ν•œλ‹€.

예제 μž…λ ₯ 1

10
10 -4 3 1 5 6 -35 12 21 -1

예제 좜λ ₯ 1

33

예제 μž…λ ₯ 2

10
2 1 -4 3 4 -4 6 5 -5 1

예제 좜λ ₯ 2

14

예제 μž…λ ₯ 3

5
-1 -2 -3 -4 -5

예제 좜λ ₯ 3

-1

풀이

DP 점화식은 λ‹€μŒκ³Ό κ°™λ‹€.

dp[i] = max(dp[i-1] + nums[i], nums[i])

μ—¬κΈ°μ„œ dp[i]λŠ” nums 리슀트의 iλ²ˆμ§ΈκΉŒμ§€μ˜ μ΅œλŒ€ 연속합을 μ˜λ―Έν•œλ‹€. λ”°λΌμ„œ dp[0]은 nums[0]κ³Ό κ°™λ‹€.

각각의 κ²½μš°μ— λŒ€ν•΄μ„œλŠ”, μ΄μ „κΉŒμ§€μ˜ μ΅œλŒ€ 연속합과 ν˜„μž¬ 값을 λ”ν•œ 것과 ν˜„μž¬ κ°’ μ€‘μ—μ„œ 큰 값을 μ„ νƒν•˜μ—¬ μ΅œλŒ€ 연속합을 κ°±μ‹ ν•œλ‹€. 이λ₯Ό λͺ¨λ“  μΈλ±μŠ€μ— λŒ€ν•΄μ„œ λ°˜λ³΅ν•˜λ©΄ DP ν…Œμ΄λΈ”μ΄ μ™„μ„±λœλ‹€.

λ§ˆμ§€λ§‰μœΌλ‘œ DP ν…Œμ΄λΈ”μ—μ„œ κ°€μž₯ 큰 값을 μ°Ύμ•„μ„œ 좜λ ₯ν•˜λ©΄ λœλ‹€.

μ½”λ“œ

λ‘κ°œμ˜ 식 λͺ¨λ‘ μ‹œκ°„ λ³΅μž‘λ„κ°€ O(n)이닀. μž…λ ₯된 μˆ˜μ—΄μ„ ν•œ 번 μˆœνšŒν•˜λ©° DP ν…Œμ΄λΈ”μ„ μ±„μš°κ³ , μ΅œλŒ€ 연속합을 κ°±μ‹ ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

ver(1)

n = int(input())  # μˆ˜μ—΄μ˜ 길이 μž…λ ₯λ°›κΈ°
nums = list(map(int, input().split()))  # μˆ˜μ—΄ μž…λ ₯λ°›κΈ°

dp = [0] * n  # DP ν…Œμ΄λΈ” μ΄ˆκΈ°ν™”
dp[0] = nums[0]  # μ΄ˆκΈ°κ°’ μ„€μ •
max_sum = nums[0]  # μ΅œλŒ€ 연속합을 μ €μž₯ν•  λ³€μˆ˜ μ΄ˆκΈ°ν™”

for i in range(1, n):
    dp[i] = max(dp[i-1] + nums[i], nums[i])  # DP 점화식
    max_sum = max(max_sum, dp[i])  # μ΅œλŒ€ 연속합 κ°±μ‹ 

print(max_sum)  # μ΅œλŒ€ 연속합 좜λ ₯

ver(2) - def μ‚¬μš©

def dp(n, nums):
    # n 크기의 리슀트 생성
    dp = [0] * n
    # 첫번째 수둜 μ΄ˆκΈ°ν™”
    dp[0] = nums[0]
    # μ΅œλŒ€ ν•©
    max_sum = nums[0]

    # λ‘λ²ˆμ§Έ μˆ˜λΆ€ν„° λκΉŒμ§€
    for i in range(1, n):
        # ν˜„μž¬ 수λ₯Ό ν¬ν•¨ν•˜λŠ” μ—°μ†λœ μˆ˜μ—΄μ˜ μ΅œλŒ€ ν•©
        dp[i] = max(dp[i-1] + nums[i], nums[i])
        # μ΅œλŒ€ ν•© κ°±μ‹ 
        max_sum = max(max_sum, dp[i])
    # μ΅œλŒ€ ν•© λ°˜ν™˜
    return max_sum

# μˆ˜μ—΄μ˜ 길이 μž…λ ₯λ°›κΈ°
n = int(input())
# μˆ˜μ—΄ μž…λ ₯λ°›κΈ°
nums = list(map(int, input().split()))
# μ΅œλŒ€ 연속합 κ΅¬ν•˜κΈ°
print(dp(n, nums))

λŒ“κΈ€λ‚¨κΈ°κΈ°