AlgorithmπŸ₯‡

2156.포도주

hae02y 2023. 11. 17. 20:22
λ°˜μ‘ν˜•

문제

νš¨μ£ΌλŠ” 포도주 μ‹œμ‹νšŒμ— κ°”λ‹€. κ·Έ 곳에 κ°”λ”λ‹ˆ, ν…Œμ΄λΈ” μœ„μ— λ‹€μ–‘ν•œ 포도주가 λ“€μ–΄μžˆλŠ” 포도주 μž”μ΄ 일렬둜 놓여 μžˆμ—ˆλ‹€. νš¨μ£ΌλŠ” 포도주 μ‹œμ‹μ„ ν•˜λ €κ³  ν•˜λŠ”λ°, μ—¬κΈ°μ—λŠ” λ‹€μŒκ³Ό 같은 두 가지 κ·œμΉ™μ΄ μžˆλ‹€.

  1. 포도주 μž”μ„ μ„ νƒν•˜λ©΄ κ·Έ μž”μ— λ“€μ–΄μžˆλŠ” ν¬λ„μ£ΌλŠ” λͺ¨λ‘ λ§ˆμ…”μ•Ό ν•˜κ³ , λ§ˆμ‹  ν›„μ—λŠ” μ›λž˜ μœ„μΉ˜μ— λ‹€μ‹œ 놓아야 ν•œλ‹€.
  2. μ—°μ†μœΌλ‘œ 놓여 μžˆλŠ” 3μž”μ„ λͺ¨λ‘ λ§ˆμ‹€ μˆ˜λŠ” μ—†λ‹€.

νš¨μ£ΌλŠ” 될 수 μžˆλŠ” λŒ€λ‘œ λ§Žμ€ μ–‘μ˜ 포도주λ₯Ό 맛보기 μœ„ν•΄μ„œ μ–΄λ–€ 포도주 μž”μ„ 선택해야 할지 κ³ λ―Όν•˜κ³  μžˆλ‹€. 1λΆ€ν„° nκΉŒμ§€μ˜ λ²ˆν˜Έκ°€ λΆ™μ–΄ μžˆλŠ” n개의 포도주 μž”μ΄ μˆœμ„œλŒ€λ‘œ ν…Œμ΄λΈ” μœ„μ— 놓여 있고, 각 포도주 μž”μ— λ“€μ–΄μžˆλŠ” ν¬λ„μ£Όμ˜ 양이 μ£Όμ–΄μ‘Œμ„ λ•Œ, 효주λ₯Ό 도와 κ°€μž₯ λ§Žμ€ μ–‘μ˜ 포도주λ₯Ό λ§ˆμ‹€ 수 μžˆλ„λ‘ ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

예λ₯Ό λ“€μ–΄ 6개의 포도주 μž”μ΄ 있고, 각각의 μž”μ— μˆœμ„œλŒ€λ‘œ 6, 10, 13, 9, 8, 1 만큼의 포도주가 λ“€μ–΄ μžˆμ„ λ•Œ, 첫 번째, 두 번째, λ„€ 번째, λ‹€μ„― 번째 포도주 μž”μ„ μ„ νƒν•˜λ©΄ 총 포도주 양이 33으둜 μ΅œλŒ€λ‘œ λ§ˆμ‹€ 수 μžˆλ‹€.

## μž…λ ₯

첫째 쀄에 포도주 μž”μ˜ 개수 n이 주어진닀. (1 ≤ n ≤ 10,000) λ‘˜μ§Έ 쀄뢀터 n+1번째 μ€„κΉŒμ§€ 포도주 μž”μ— λ“€μ–΄μžˆλŠ” ν¬λ„μ£Όμ˜ 양이 μˆœμ„œλŒ€λ‘œ 주어진닀. ν¬λ„μ£Όμ˜ 양은 1,000 μ΄ν•˜μ˜ 음이 μ•„λ‹Œ μ •μˆ˜μ΄λ‹€.

## 좜λ ₯

첫째 쀄에 μ΅œλŒ€λ‘œ λ§ˆμ‹€ 수 μžˆλŠ” ν¬λ„μ£Όμ˜ 양을 좜λ ₯ν•œλ‹€.

μ‹œκ°„ μ œν•œ λ©”λͺ¨λ¦¬ μ œν•œ 제좜 μ •λ‹΅ 맞힌 μ‚¬λžŒ μ •λ‹΅ λΉ„μœ¨
2 초 128 MB 133020 45346 32776 32.622%

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

풀이

μ•Œκ³ λ¦¬μ¦˜ 흐름

μ€‘μš”ν•˜κ²Œ 봐야할뢀뢄은

  1. ν¬λ„μ£ΌλŠ” μ—°μ†μœΌλ‘œ 3μž”μ„ λͺ¨λ‘ λ§ˆμ‹€μˆ˜μ—†λ‹€λŠ” 점이닀.

즉 ν˜„μž¬ μœ„μΉ˜μ—μ„œ OOX , OXO , XOO 의 κ²½μš°μ€‘ 어떀것이 제일 많이 λ¨Ήμ„μˆ˜μžˆλŠ” κ²½μš°μΈμ§€ νŒλ‹¨ν•΄μ„œ λ©”λͺ¨μ΄μ œμ΄μ…˜ ν•΄μ£Όλ©΄ λœλ‹€. (맨였λ₯Έμͺ½μ΄ ν˜„μž¬ μœ„μΉ˜μ΄λ―€λ‘œ, ν˜„μž¬ μœ„μΉ˜λ₯Ό κΈ°μ€€μœΌλ‘œ ν•˜λ‚˜μ „, λ‘κ°œμ „ 경우λ₯Ό μ‚΄νŽ΄λ³΄λ©΄λœλ‹€.)

예λ₯Όλ“€μ–΄ indexκ°€ iκ°€ 2μΌλ•Œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄,

<OOX>

와인 μˆœμ„œ 0 1 2 3 4 5 6
선택 μ—¬λΆ€ O O X        

<OXO>

와인 μˆœμ„œ 0 1 2 3 4 5 6
선택 μ—¬λΆ€ O X O        

<XOO>

와인 μˆœμ„œ 0 1 2 3 4 5 6
선택 μ—¬λΆ€ X O O        

이런 μˆœμ„œκ°€ λ§Œλ“€μ–΄μ§€κ²Œ λœλ‹€.

그럼 점화식을 λ½‘μ•„λ³΄μž.

1. OOX : dp[i-1]
2. OXO : dp[i-2] + wine[i]
3. XOO : dp[i-3] + wine[i-1] + wine[i]

μ΄λ ‡κ²Œ 3κ°€μ§€μ˜ κ²½μš°μ€‘ κ°€μž₯ max인 값을 dp[i] 에 μ €μž₯μ‹œν‚¨λ‹€. 그리고 μ΅œμ’…μ μœΌλ‘œ dp[n-1]에 μ €μž₯λ˜λŠ” μˆ˜κ°€ λ§ˆμ‹€μˆ˜μžˆλŠ” μ™€μΈμ˜ μ΅œλŒ“κ°’μ΄ 될것이닀.

dp[0]κ³Ό dp[1], dp[2]λŠ” μ˜ˆμ™Έμ²˜λ¦¬ ν•΄μ€€λ‹€.

  • dp[0]은 wines[0] μžμ²΄κ°€ μ΅œλŒ“κ°’μ΄ λœλ‹€.
  • dp[1]은 wines[0] + wines[1]κ°€ μ΅œλŒ€κ°’μ΄ λœλ‹€.
  • dp[2]λŠ” Math.max(dp[1], wines[0]+wines[2], wines[1]+wines[2])λ₯Ό κ΅¬ν•œλ‹€.

μ½”λ“œ

import java.util.Scanner;  

public class ν¬λ„μ£Όμ‹œμ‹ {  

    public static void main(String[] args) {  

        Scanner sc = new Scanner(System.in);  

        int n = sc.nextInt();  


        int[] wine = new int[n];  
        int[] dp = new int[n];  

        for(int i=0; i<n; i++){  
            wine[i] = sc.nextInt();  
        }  

        dp[0] = wine[0];  

        for(int i=1; i<n; i++){  
            if(i==1){  
                dp[1] = wine[0] + wine[1];  
                continue;  
            }  
            if(i==2){  
                dp[2] = Math.max(dp[1], Math.max(wine[0]+wine[2],wine[1]+wine[2]));  
                continue;  
            }  
            dp[i] = Math.max(dp[i-1], Math.max(dp[i-2]+wine[i],dp[i-3]+wine[i-1]+wine[i]));  
        }  

        System.out.println(dp[n-1]);  
        sc.close();  
    }  
}

DPλ¬Έμ œλŠ” 정말 풀어도 적응이 μž˜μ•ˆλœλ‹€... λ©”λͺ¨μ΄μ œμ΄μ…˜κ³Ό 점화식을 λ½‘μ•„λ‚΄λŠ”λ°©λ²•μ„ 계속 κ³ λ―Όν•΄λ³΄μž.

λ°˜μ‘ν˜•