λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€/4단계

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ Lv4] : λ„λ‘‘μ§ˆ

by Jaeguk 2022. 6. 29.
문제 링크

https://programmers.co.kr/learn/courses/30/lessons/42897

 

μ½”λ”©ν…ŒμŠ€νŠΈ μ—°μŠ΅ - λ„λ‘‘μ§ˆ

도둑이 μ–΄λŠ λ§ˆμ„μ„ ν„Έ κ³„νšμ„ ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 이 λ§ˆμ„μ˜ λͺ¨λ“  집듀은 μ•„λž˜ κ·Έλ¦Όκ³Ό 같이 λ™κ·Έλž—κ²Œ λ°°μΉ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. 각 집듀은 μ„œλ‘œ μΈμ ‘ν•œ 집듀과 λ°©λ²”μž₯μΉ˜κ°€ μ—°κ²°λ˜μ–΄ 있기 λ•Œλ¬Έμ— μΈμ ‘ν•œ

programmers.co.kr

도둑이 μ›ν˜•μœΌλ‘œ λ°°μΉ˜λ˜μ–΄μžˆλŠ” 집을 ν„Έ λ•Œ, ν„Έκ³ μžν•˜λŠ” 집과 μΈμ ‘ν•œ 집은 ν„Έμ§€μ•ŠλŠ”λ‹€. μ΄λ•Œ 도둑이 ν›”μΉ  수 μžˆλŠ” 돈의 μ΅œλŒ€κ°’μ„ λ¦¬ν„΄ν•˜λŠ” 문제.

 

풀이

λ¨Όμ € μš°λ¦¬κ°€ κ°€μž₯ κ°„λ‹¨ν•˜κ²Œ λ– μ˜¬λ¦΄ 수 μžˆλŠ” 방법은 집을 ν„°λŠ” λͺ¨λ“  경우의 수λ₯Ό λ‹€ λ– μ˜¬λ €λ³΄λŠ” 방법이닀.

ν•˜μ§€λ§Œ 집은 μ΅œλŒ€ 1000000κ°œκ°€ μžˆμ„ 수 μžˆμœΌλ―€λ‘œ 1000000개의 집 쀑에 μ΄μ›ƒν•˜μ§€ μ•Šκ³  1κ°œλΆ€ν„° μ΅œλŒ€ 500000개의 집을 μ„ νƒν•˜λŠ” 경우의 수λ₯Ό λͺ¨λ‘ λ‹€ λ”°μ Έλ΄μ•Όν•˜κΈ° λ•Œλ¬Έμ— μ—„μ²­λ‚œ μ‹œκ°„μ΄ μ†Œμš”λœλ‹€.

λ”°λΌμ„œ 이 방법은 μ‹œκ°„μ΄ˆκ³Ό 였λ₯˜κ°€ λ‚  것이닀.

 

κ·Έλ ‡λ‹€λ©΄ DPλ₯Ό μ΄μš©ν•΄μ„œ 졜적의 값을 μ°ΎλŠ” 방법이 μžˆλ‹€.

μ΄λ•Œ DPλ°°μ—΄μ˜ μΈλ±μŠ€λŠ” μ§‘μ˜ 번호λ₯Ό μ˜λ―Έν•  것이닀.

ν•˜μ§€λ§Œ μ΄μ›ƒν•œ 집은 ν›”μΉ  수 μ—†λ‹€λŠ” 쑰건이 μžˆμœΌλ―€λ‘œ μ΄μ „μ˜ 집을 λ°©λ¬Έν–ˆλŠ”μ§€ 여뢀도 μ€‘μš”ν•˜λ‹€.

λ”°λΌμ„œ DP배열을 DP[도둑이 λ°©λ¬Έν–ˆλŠ”μ§€ μ—¬λΆ€][μ§‘μ˜ 번호] μ΄λ ‡κ²Œ λ§Œλ“€ 수 μžˆλ‹€.

도둑이 λ°©λ¬Έν–ˆλŠ”μ§€μ˜ μ—¬λΆ€λŠ” 0, 1둜 ν‘œν˜„ν•œλ‹€.

이것을 λ°”νƒ•μœΌλ‘œ 점화식을 μ„Έμ›Œλ³΄λ©΄

DP[ 1 ][ i ] = DP[ 0 ][ i - 1 ] + money[ i ] κ°€ λœλ‹€. (i번째 집을 λ°©λ¬Έν•  경우)

=> i번째 집을 λ°©λ¬Έν•˜λ €λ©΄ i - 1번째 집은 방문을 ν•˜μ§€ μ•Šμ•˜μ–΄μ•Όν•œλ‹€.

DP[ 0 ][ i ] = max( DP[ 0 ][ i - 1 ] , DP[ 1 ][ i - 1 ] ) κ°€ λœλ‹€. (i번째 집을 λ°©λ¬Έν•˜μ§€ μ•Šμ„ 경우)

=> i번째 집을 λ°©λ¬Έν•˜μ§€ μ•Šμ•˜μ„ 경우 ν›”μΉ  수 μžˆλŠ” μ΅œλŒ€ κΈˆμ•‘μ€ i - 1번째 집을 λ°©λ¬Έν•˜κ±°λ‚˜ λ°©λ¬Έν•˜μ§€ μ•Šμ€ 2가지 경우 쀑 큰 κ°’κ³Ό κ°™λ‹€.

 

점화식은 μ„Έμ› μ§€λ§Œ μ—¬κΈ°μ„œ λ¬Έμ œκ°€ μžˆλ‹€.

λ§ˆμ§€λ§‰ N-1번째 집(첫 집을 0번째 집이라 생각)에 λ°©λ¬Έν•˜λ € ν•  λ•Œ, 점화식에 μ˜ν•΄μ„œ

DP[ 1 ][ N - 1 ] = DP[ 0 ][ N - 1 ] + money[ N - 1 ] 인데 μ—¬κΈ°μ„œ DP[ 0 ][ N - 1 ] 에 μ €μž₯λ˜μ–΄ μžˆλŠ” 값이 0번째 집을 λ°©λ¬Έν•΄μ„œ λ§Œλ“€μ–΄ 진 값인지 μ•„λ‹Œμ§€ μ•Œ μˆ˜κ°€ μ—†λ‹€. 

0번째 집을 λ°©λ¬Έν–ˆμ„ κ²½μš°λŠ” λ§ˆμ§€λ§‰ N-1번째 집을 λ°©λ¬Έν•˜μ§€ λͺ»ν•˜λŠ”데 이것을 체크할 방법이 μ—†λ‹€.

 

κ·Έλž˜μ„œ λ‚΄κ°€ μƒκ°ν•œ 방법은 첫번째 집을 λ°©λ¬Έν–ˆλ‹€κ³  μƒκ°ν•˜κ³  N-2번째 μ§‘κΉŒμ§€ λ„λ‹¬ν–ˆμ„ λ•Œ ν›”μΉ  수 μžˆλŠ” μ΅œλŒ€ κΈˆμ•‘κ³Ό

첫번째 집을 λ°©λ¬Έν•˜μ§€ μ•Šμ•˜λ‹€κ³  μƒκ°ν•˜κ³  N-1번째 μ§‘κΉŒμ§€ λ„λ‹¬ν–ˆμ„ λ•Œ ν›”μΉ  수 μžˆλŠ” μ΅œλŒ€ κΈˆμ•‘ 쀑 큰 값을 λ‹΅μœΌλ‘œ μƒκ°ν•˜κΈ°λ‘œ ν–ˆλ‹€.

첫번째 집을 λ°©λ¬Έν–ˆλ‹€κ³  μƒκ°ν–ˆμ„ λ•ŒλŠ” μ™œ N-1λ²ˆμ§Έκ°€ μ•„λ‹Œ N-2λ²ˆμ§ΈκΉŒμ§€ λ„λ‹¬ν–ˆμ„ λ•Œ μ΅œλŒ€κ°’μ„ μ²΄ν¬ν•˜λŠλƒ

μ–΄μ§œν”Ό 첫번째 집을 λ°©λ¬Έν–ˆλ‹€λ©΄ λ§ˆμ§€λ§‰ 집은 λ°©λ¬Έν•˜μ§€ λͺ»ν•˜κΈ°λ•Œλ¬Έμ— λ§ˆμ§€λ§‰ 집은 μ˜λ―Έκ°€ μ—†λ‹€.

 

μ½”λ“œ μž‘μ„±
 
#include <string>
#include <vector>
#include <string.h>
using namespace std;
const int MAX_N = 1000000 + 5;
int DP[2][MAX_N];
int solution(vector<int> money) {
    int answer = 0;
    int N = money.size(); //μ§‘μ˜ κ°œμˆ˜
    DP[0][0= 0;
    DP[1][0= 0;
    for(int i = 1; i<N; i++){
        DP[0][i] = max(DP[1][i-1], DP[0][i-1]);
        DP[1][i] = DP[0][i-1+ money[i];
    }
    answer = max(DP[1][N-1], DP[0][N-1]);
    memset(DP,0,sizeof(DP));
    DP[1][0= money[0];
    for(int i = 1; i<N-1; i++){
        DP[0][i] = max(DP[1][i-1], DP[0][i-1]);
        DP[1][i] = DP[0][i-1+ money[i];
    }
    answer = max(answer, max(DP[0][N-2], DP[1][N-2]));
    return answer;
}
cs
728x90