λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Algorithm

[λ°±μ€€] 2156번: 포도주 μ‹œμ‹(DP)

by 주발2 2020. 2. 28.
λ°˜μ‘ν˜•

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

 

2156번: 포도주 μ‹œμ‹

νš¨μ£ΌλŠ” 포도주 μ‹œμ‹νšŒμ— κ°”λ‹€. κ·Έ 곳에 κ°”λ”λ‹ˆ, ν…Œμ΄λΈ” μœ„μ— λ‹€μ–‘ν•œ 포도주가 λ“€μ–΄μžˆλŠ” 포도주 μž”μ΄ 일렬둜 놓여 μžˆμ—ˆλ‹€. νš¨μ£ΌλŠ” 포도주 μ‹œμ‹μ„ ν•˜λ €κ³  ν•˜λŠ”λ°, μ—¬κΈ°μ—λŠ” λ‹€μŒκ³Ό 같은 두 가지 κ·œμΉ™μ΄ μžˆλ‹€. 포도주 μž”μ„ μ„ νƒν•˜λ©΄ κ·Έ μž”μ— λ“€μ–΄μžˆλŠ” ν¬λ„μ£ΌλŠ” λͺ¨λ‘ λ§ˆμ…”μ•Ό ν•˜κ³ , λ§ˆμ‹  ν›„μ—λŠ” μ›λž˜ μœ„μΉ˜μ— λ‹€μ‹œ 놓아야 ν•œλ‹€. μ—°μ†μœΌλ‘œ 놓여 μžˆλŠ” 3μž”μ„ λͺ¨λ‘ λ§ˆμ‹€ μˆ˜λŠ” μ—†λ‹€. νš¨μ£ΌλŠ” 될 수 μžˆλŠ” λŒ€λ‘œ λ§Žμ€ μ–‘μ˜ 포도주λ₯Ό 맛보기 μœ„ν•΄μ„œ μ–΄λ–€ 포도주 μž”μ„ 선택해야 할지 κ³ 

www.acmicpc.net

μ½”λ“œ

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		int[] arr = new int[n];
		int[] dp = new int[n];
		for(int i=0; i<n; i++)
			arr[i] = scan.nextInt();
		
		// μž”μ˜ κ°œμˆ˜κ°€ 1μΌλ•Œ -> κ·Έμž” λ§ˆμ‹œλ©΄ 됨
		if(n>=1) 
			dp[0] = arr[0];
		// μž”μ˜ κ°œμˆ˜κ°€ 2μΌλ•Œ -> μ²«μž” + λ‘λ²ˆμ§Έμž” λ§ˆμ‹œλ©΄ 됨
		if(n>=2) 
			dp[1] = arr[0] + arr[1];
		// μž”μ˜ κ°œμˆ˜κ°€ 3μΌλ•Œ -> (μ²«μž”+λ‘λ²ˆμ§Έμž”) , (μ²«μž”+μ„Έλ²ˆμ§Έμž”) , (λ‘λ²ˆμ§Έμž”+μ„Έλ²ˆμ§Έμž”) 쀑 큰 κ°’ 비ꡐ 
		if(n>=3)
			dp[2] = Math.max(dp[1], Math.max(arr[0]+arr[2], arr[1]+arr[2]));
		
		for(int i=3; i<n; i++) {
			dp[i] = Math.max(dp[i-3]+arr[i-1]+arr[i], dp[i-2]+arr[i]);
			dp[i] = Math.max(dp[i], dp[i-1]);
		}
		
		System.out.println(dp[n-1]);
		scan.close();
	}

}

풀이

DP(λ™μ κ³„νšλ²•) λ¬Έμ œλŠ” 경우의 수λ₯Ό μ°Ύκ³ , 점화식을 μ„Έμš°λŠ”κ²ƒμ΄ μš°μ„ μΈ 것 κ°™λ‹€.

μœ„ λ¬Έμ œμ—μ„œ μ€‘μš”ν•œ 쑰건은 2번째인 λ‹€μŒ 쑰건이닀.

* μ—°μ†μœΌλ‘œ 놓여 μžˆλŠ” 3μž”μ„ λͺ¨λ‘ λ§ˆμ‹€ μˆ˜λŠ” μ—†λ‹€.

 

μœ„ λ¬Έμ œμ—μ„œ ν˜„μž¬ λ¨ΉλŠ” ν¬λ„μ£Όμ˜ 합을 μ΅œλŒ€λ‘œ λ§Œλ“€ 경우λ₯Ό 생각해보면

 1) ν˜„μž¬ 포도주λ₯Ό λ§ˆμ‹œκ³ , 이전 포도주λ₯Ό λ§ˆμ‹  경우

 2) ν˜„μž¬ 포도주λ₯Ό λ§ˆμ‹œκ³ , 이전 포도주λ₯Ό λ§ˆμ‹œμ§€ μ•Šμ€ 경우

 3) ν˜„μž¬ 포도주λ₯Ό λ§ˆμ‹œμ§€ μ•Šμ€ 경우

둜 총 μ„Έκ°œμ˜ 경우둜 λ‚˜λˆŒ 수 μžˆλ‹€.

 

 

dp[i] : iλ²ˆμ§ΈκΉŒμ§€ λ§ˆμ‹  포도주 쀑 μ΅œλŒ€λ‘œ λ§ˆμ‹€μˆ˜ μžˆλŠ” μ–‘

arr[i] : iλ²ˆμ§Έμ— λ§ˆμ‹œλŠ” ν¬λ„μ£Όμ˜ μ–‘

 

 

μœ„μ™€ 같이 λ§ˆμ§€λ§‰μž”, λ§ˆμ§€λ§‰ μ•ž μž”μ„ λ§ˆμ…¨μ„ 경우, λ§ˆμ‹€μˆ˜ μžˆλŠ” ν¬λ„μ£Όμ˜ μ΅œλŒ€ 양은

dp[i] = dp[i-3] + arr[i-1] + arr[i] 이닀.

 

 

두 λ²ˆμ§Έλ‘œλŠ”, λ§ˆμ§€λ§‰μž”μ„ λ§ˆμ‹œκ³ , κ·Έ μ•žμž”μ„ λ§ˆμ‹œμ§€ μ•Šμ•˜μ„ 경우λ₯Ό 보자.

μœ„μ™€ κ°™μ„λ•Œ λ§ˆμ‹€μˆ˜ μžˆλŠ” ν¬λ„μ£Όμ˜ μ΅œλŒ€ 양은

dp[i] = dp[i-2] + arr[i] 이닀.

 

 

μ„Έ 번째둜 λ§ˆμ§€λ§‰μž”μ„ λ§ˆμ‹œμ§€ μ•Šμ•˜μ„ κ²½μš°μ—λŠ” κ·Έ μ•ž λ‘μž”μ„ λ§ˆμ‹œκ²Œ λœλ‹€.

λ”°λΌμ„œ μœ„μ™€ κ°™μ„λ•Œ λ§ˆμ‹€μˆ˜ μžˆλŠ” ν¬λ„μ£Όμ˜ μ΅œλŒ€ 양은

dp[i] = dp[i-1] 이닀.

 

μœ„μ—μ„œ κ΅¬ν•œ 3개의 점화식 쀑 μ΅œλŒ“κ°’μ„ 찾으면 λœλ‹€.

 

dp[i-3] + arr[i-1] + arr[i] , dp[i-2] + arr[i] , dp[i-1]

λ°˜μ‘ν˜•

λŒ“κΈ€