𝘚𝘭𝘰𝘸 𝘣𝘢𝘡 𝘴𝘡𝘦𝘒π˜₯𝘺

[λ°±μ€€] 2156번: 포도주 μ‹œμ‹ - C++ λ³Έλ¬Έ

μ½”λ”©ν…ŒμŠ€νŠΈ μ€€λΉ„/λ°±μ€€

[λ°±μ€€] 2156번: 포도주 μ‹œμ‹ - C++

.23 2021. 7. 17. 00:31
문제

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

 

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

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

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

 

μž…λ ₯

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

 

좜λ ₯

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

 


DPλ₯Ό μ‚¬μš©ν•˜λŠ” 문제 쀑 쑰금 κΉŒλ‹€λ‘œμ› λ˜ 문제.

사싀... μ˜€λŠ˜κΉŒμ§€λ§Œ 해도 이게 μ™œ 닡이 μ΄λŸ°μ§€ 이해λ₯Ό λͺ»ν–ˆλ˜ λ¬Έμ œλ‹€. ν’€μ—ˆλ˜ μˆœμ„œλŒ€λ‘œ ν•˜λ‚˜μ”© 풀이쀑이라 μ›λž˜ ν’€μ΄ν•˜λ €λ˜ λ¬Έμ œκ°€ λ”°λ‘œ μžˆμ—ˆλŠ”λ° 였늘 ν’€μ—ˆλ˜ λ¬Έμ œκ°€ 포도주 μ‹œμ‹ λ¬Έμ œμ™€ 맀우 λΉ„μŠ·ν•΄μ„œ 원리λ₯Ό μ΄ν•΄ν•œ 덕에 까먹기 전에 μ–Όλ₯Έ ν¬μŠ€νŒ…ν•œλ‹€.

 

ν¬λ„μ£ΌλŠ” 두 μž”κΉŒμ§€ 연달아 λ§ˆμ‹€ 수 μžˆμ§€λ§Œ, μ„Έ μž”μ€ 연달아 λ§ˆμ‹œμ§€ λͺ»ν•œλ‹€. κ·ΈλŸ¬λ―€λ‘œ N번째 μž”μ„ λ§ˆμ‹œκ²Œ 될 차둀라고 κ°€μ •ν–ˆμ„ λ•Œ λ‚˜μ˜¬ 수 μžˆλŠ” 상황은 λ‹€μŒκ³Ό κ°™λ‹€.

 

  1. (N - 1)번째 μž”μ„ λ§ˆμ‹œμ§€ μ•Šμ€ 경우
  2. (N - 1)번째 μž”μ„ λ§ˆμ‹  경우

1번의 상황은 (N - 1)번째 μž”μ„ λ§ˆμ‹œμ§€ μ•Šκ³  κ±΄λ„ˆλ›°μ—ˆμœΌλ―€λ‘œ, (N - 2)번째 μž”κΉŒμ§€ λ§ˆμ‹  ν¬λ„μ£Όμ˜ 양에 N번째 μž”μ— λ‹΄κΈ΄ 양을 더해쀀닀. 이와 같은 상황을 μ‹μœΌλ‘œ ν‘œν˜„ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

 

D[N] = D[N - 2] + wine[N]

 

2번의 상황은 (N - 1)번째 μž”μ„ λ§ˆμ…¨μœΌλ―€λ‘œ, 연달아 μ„Έ μž”μ„ λ§ˆμ‹€ 수 μ—†κΈ° λ•Œλ¬Έμ— (N - 2)번째 μž”μ€ κ±΄λ„ˆλ›°κ²Œλœλ‹€. κ·Έλ ‡κ²Œ λ˜μ–΄ (N - 3)번째 μž”κΉŒμ§€ λ§ˆμ‹  ν¬λ„μ£Όμ˜ 양에 (N - 1)번째 μž”μ— λ‹΄κΈ΄ μ–‘κ³Ό N번째 μž”μ— λ‹΄κΈ΄ 양을 더해쀀닀. 이λ₯Ό μ‹μœΌλ‘œ ν‘œν˜„ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

 

D[N] = D[N - 3] + wine[N - 1] + wine[N]

 

이 λ•Œ, 1번과 2번 쀑 λ‘˜ 쀑에 μ–΄λŠ κ²½μš°κ°€ 더 λ§ˆμ‹  κ²½μš°μΈμ§€ λͺ¨λ₯΄κΈ° λ•Œλ¬Έμ— λΉ„κ΅ν•΄μ£ΌλŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 더 큰 값을 κ°€λ €λ‚Έλ‹€. λ”°λΌμ„œ 점화식은 λ‹€μŒκ³Ό κ°™λ‹€.

 

D[N] = max(D[N - 2] + wine[N], D[N - 3] + wine[N - 1] + wine[N])

 

κ·ΈλŸ¬λ‚˜ μ—¬κΈ°μ„œ 또 κ³ λ €ν•΄μ•Ό 될 μ€‘μš”ν•œ 점은 N번째 μž”μ„ λ§ˆμ‹œμ§€ μ•Šμ•˜μ„ 경우, 즉 두 μž”μ„ μ—°μ†μœΌλ‘œ μ•ˆλ§ˆμ…¨μ„ κ²½μš°λ„ κ³ λ €ν•΄μ•Όλœλ‹€.

예λ₯Ό λ“€μ–΄ { 10, 13, 1, 2, 5, 11 } 을 μœ„μ˜ μ ν™”μ‹λ§Œ μ΄μš©ν•˜μ—¬ ν’€λ©΄ 10, 13, 2, 11 이 μ„ νƒλ˜μ–΄ 36이 λ‚˜μ˜¨λ‹€. ν•˜μ§€λ§Œ μ‹€μ œ 닡은 10, 13, 5, 11둜 39κ°€ λ‚˜μ™€μ•Ό ν•œλ‹€. λ”°λΌμ„œ μœ„μ™€ 같이 κ΅¬ν•œ D[N]κ³Ό D[N - 1]의 값을 λ‹€μ‹œ ν•œλ²ˆ λΉ„κ΅ν•˜μ—¬ 더 큰 값이 λ‚˜μ˜€λŠ” 경우λ₯Ό μ‹€μ œ D[N]의 값에 λŒ€μž…ν•΄μ•Όλœλ‹€.

 

D[N] = max(D[N], D[N - 1])

 

λ¬Έμ œλŠ” Bottom-up λ°©μ‹μœΌλ‘œ ν’€μ—ˆλ‹€.

 

μ½”λ“œ
#include <cstdio>
#define MAX 10003

int DP(int num);
int max(int num1, int num2) { return num1 > num2 ? num1 : num2; }

int main(void) {
    int n;
    scanf("%d", &n);
    printf("%d\n", DP(n));
    return 0;
}

int DP(int num) {
    int wine[MAX] = { 0 };
    int memo[MAX] = { 0 };

    for(int i = 3; i < (num + 3); i++) {
        scanf("%d", &wine[i]);
    }
    
    for(int i = 3; i < (num + 3); i++) {
        memo[i] = max(memo[i - 2] + wine[i], memo[i - 3] + wine[i - 1] + wine[i]);
        memo[i] = max(memo[i - 1], memo[i]);
    }

    return memo[num + 2];
}

 

Comments