[c++] ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค :: ๋„๋‘‘์งˆ

๋ฌธ์ œ

1. ๋ฌธ์ œ ์„ค๋ช…

๋„๋‘‘์ด ์–ด๋Š ๋งˆ์„์„ ํ„ธ ๊ณ„ํš์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋งˆ์„์˜ ๋ชจ๋“  ์ง‘๋“ค์€ ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ๋™๊ทธ๋ž—๊ฒŒ ๋ฐฐ์น˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

image.png

๊ฐ ์ง‘๋“ค์€ ์„œ๋กœ ์ธ์ ‘ํ•œ ์ง‘๋“ค๊ณผ ๋ฐฉ๋ฒ”์žฅ์น˜๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ ‘ํ•œ ๋‘ ์ง‘์„ ํ„ธ๋ฉด ๊ฒฝ๋ณด๊ฐ€ ์šธ๋ฆฝ๋‹ˆ๋‹ค.

๊ฐ ์ง‘์— ์žˆ๋Š” ๋ˆ์ด ๋‹ด๊ธด ๋ฐฐ์—ด money๊ฐ€ ์ฃผ์–ด์งˆ ๋•Œ, ๋„๋‘‘์ด ํ›”์น  ์ˆ˜ ์žˆ๋Š” ๋ˆ์˜ ์ตœ๋Œ“๊ฐ’์„ return ํ•˜๋„๋ก solution ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”.

 

2. ์ œํ•œ์‚ฌํ•ญ

  • ์ด ๋งˆ์„์— ์žˆ๋Š” ์ง‘์€ 3๊ฐœ ์ด์ƒ 1,000,000๊ฐœ ์ดํ•˜์ž…๋‹ˆ๋‹ค.
  • money ๋ฐฐ์—ด์˜ ๊ฐ ์›์†Œ๋Š” 0 ์ด์ƒ 1,000 ์ดํ•˜์ธ ์ •์ˆ˜์ž…๋‹ˆ๋‹ค.

 

ํ’€์ด

  • ๋งŒ์•ฝ ์™„์ „ํƒ์ƒ‰์œผ๋กœ ํ•˜๊ณ ์ž ํ–ˆ๋‹ค๋ฉด?
    • ๋ฐ˜๋ณต์„ index 0๋ถ€ํ„ฐ n-1๊นŒ์ง€ ๋Œ๋ฉด์„œ ํ•ด๋‹น ์ง‘์—์„œ ์‹œ์ž‘ํ•ด์„œ ๋‚˜ํƒ€๋‚˜๋Š” ์ตœ๋Œ€์˜ money๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ์Œ
    • ํ•˜์ง€๋งŒ index 2๋ฅผ ๊ณ ๋ฅธ๋‹ค๋ฉด, ์ง‘์˜ ๊ฐœ์ˆ˜๊ฐ€ ์ง์ˆ˜์ผ ๋•Œ index 0์„ ๊ณ ๋ฅผ ์ˆ˜ ์žˆ๊ณ  ํ™€์ˆ˜์ผ ๋•Œ index 1์„ ๊ณ ๋ฅผ ์ˆ˜ ์žˆ์Œ
      • ๊ณ ๋กœ index 0๊ณผ 1๋งŒ ๊ณ ๋ คํ•˜๋ฉด ๋จ
  • DP
    • 3๋ฒˆ์งธ <์žฌ๊ท€ํ•จ์ˆ˜> ์ฝ”๋“œ
      • top-down ๋ฐฉ์‹์œผ๋กœ ํ•ด๋‹น index์—์„œ์˜ maxMoney ๊ตฌํ•ด์„œ ์ €์žฅ
    • ์ ํ™”์‹ ํ’€์ด ์ฝ”๋“œ
      • DP๋Š” ๋ฐฐ์—ด์„ ์ด์šฉํ•œ ์ ํ™”์‹ ํ’€์ด๋ฅผ ๋จผ์ € ์ƒ๊ฐํ•ด๋ณด๊ณ  ์•ˆ๋˜๋ฉด ์žฌ๊ท€ํ•จ์ˆ˜๋กœ ๋Œ๋ฆฌ์ž.
      • 1์ฐจ์› ๋ฐฐ์—ด(arr)์—์„œ ์ง‘์˜ index๋ฅผ ๋ฐฐ์—ด์˜ index, ๊ฐ’์„ ์ตœ๋Œ€ money๋กœ ๋ณด์ž.
      • 1๋ฒˆ์งธ top-down (๋ฐฐ์—ด์œผ๋กœ ๋ดค์„ ๋•Œ, ๋งˆ์ง€๋ง‰ ์š”์†Œ๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด ์ด์ „ ์š”์†Œ๋ฅผ ์ด์šฉ) ์ฝ”๋“œ
        • ํ˜„์žฌ index๋ฅผ i๋ผ ํ•  ๋•Œ,
        • arr[i] = max(arr[i-2]+ money[i], arr[i-1])
      • 2๋ฒˆ์งธ bottom-up (๋ฐฐ์—ด์œผ๋กœ ๋ดค์„ ๋•Œ, ์ฒซ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ์ด์šฉํ•ด์„œ ๋งˆ์ง€๋ง‰ ์š”์†Œ๋“ค์„ ์ƒ์„ฑ) ์ฝ”๋“œ
        • arr[i+2] = max(arr[i+2], arr[i] + money[i+2])
        • arr[i+1] = max(arr[i+1], arr[i])

 

์ฝ”๋“œ

1. <์ ํ™”์‹ top-down>

#include <string>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;
int memo[1000001];
int memo2[1000001];

int solution(vector<int> money) {
    // top-down
    int answer = 0;
    memset(memo, -1, sizeof(memo));
    memset(memo2, -1, sizeof(memo2));

    int size = money.size();

    memo[0] = money[0];
    memo[1] = memo[0];
    for(int i=2; i<size-1; i++){ // ์ฒซ๋ฒˆ์งธ ์š”์†Œ์—์„œ ์‹œ์ž‘ํ•˜๋ฉด ๋งˆ์ง€๋ง‰ ์š”์†Œ ์ œ์™ธ
        memo[i] = max(memo[i-2] + money[i], memo[i-1]);
    }

    memo2[0] = 0;
    memo2[1] = money[1];
    for(int i=2; i<size; i++){ // ๋‘๋ฒˆ์งธ ์š”์†Œ์—์„œ ์‹œ์ž‘ํ•˜๋ฉด ๋งˆ์ง€๋ง‰ ์š”์†Œ ํฌํ•จ
        memo2[i] = max(memo2[i-2] + money[i], memo2[i-1]);
    }

    answer = max(memo[size-2], memo2[size-1]);

    return answer;
}

 

2. <์ ํ™”์‹ bottom-up>

#include <string>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;
int memo[1000001];
int memo2[1000001];

int solution(vector<int> money) {
    // bottom-up
    int answer = 0;
    memset(memo, -1, sizeof(memo));
    memset(memo2, -1, sizeof(memo2));

    int size = money.size();

    memo[0] = money[0];
    memo[1] = memo[0];
    for(int i=0; i<size-2; i++){
        memo[i+2] = max(memo[i+2], memo[i] + money[i+2]);
        memo[i+1] = max(memo[i+1], memo[i]);
        // size-2๋ฅผ ๊ตฌํ•˜๋Š”๋ฐ ์ตœ๋Œ€ size-1๊นŒ์ง€ ๋‚˜์˜ค๋ฏ€๋กœ ํ•„์š”์—†๋Š” ์—ฐ์‚ฐ์ด ์ถ”๊ฐ€๋จ
    }

    memo2[0] = 0;
    memo2[1] = money[1];
    for(int i=0; i<size-1; i++){
        memo2[i+2] = max(memo2[i+2], memo2[i] + money[i+2]);
        memo2[i+1] = max(memo2[i+1], memo2[i]);
    }

    answer = max(memo[size-2], memo2[size-1]);

    return answer;
}

 

3. ์˜ค๋‹ต์ฝ”๋“œ <์žฌ๊ท€ํ•จ์ˆ˜>

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>

using namespace std;

int N;
vector<int> moneyArr;
int memo[1000001];

bool isBitmapEmpty(vector<int>& vec) {
    for (int i = 0; i < vec.size(); i++) {
        if (vec[i] == 1)
            return false;
    }
    return true;
}

int stillMoney(vector<int>& bitmap, int prev) {
    if (isBitmapEmpty(bitmap)) // ๋”์ด์ƒ ํ›”์น ์ˆ˜ ์žˆ๋Š” ์ง‘์ด ์—†์œผ๋ฉด 0 return
        return 0;

    int maxMoney = 0; // ์ตœ๋Œ€ ํ›”์นœ ๋ˆ
    for (int i = prev; i < N; i++) { // ํ•œ๋ฐ”ํ€ด ๋Œ๊ฒŒ ๋˜๋ฉด ์ž๋™์œผ๋กœ for๋ฌธ ์ข…๋ฃŒ
        vector<int> houses(bitmap);
        if (houses[i] == 0) // ํ›”์น  ์ˆ˜ ์—†์œผ๋ฉด
            continue;

        if (memo[i] != -1) {
            // memo๊ฐ€ ์žˆ์œผ๋ฉด
            maxMoney = max(maxMoney, memo[i]);
            continue;
        }

        houses[i] = 0; // ์ด๋ฏธ ํ›”์ณค์œผ๋ฏ€๋กœ ๋”์ด์ƒ ํ›”์น  ์ˆ˜ ์—†์Œ
        houses[(i - 1 + N) % N] = 0; // ์ด์ „ ์ง‘์€ ์ธ์ ‘ํ•ด์žˆ์œผ๋ฏ€๋กœ ํ›”์น  ์ˆ˜ ์—†์Œ
        houses[(i + 1) % N] = 0; // ์ดํ›„ ์ง‘

        int tmpMoney = stillMoney(houses, i + 2) + moneyArr[i];
        if (maxMoney < tmpMoney) {
            maxMoney = tmpMoney;
        }
    }
    memo[prev] = maxMoney;
    return maxMoney;
}

int solution(vector<int> money) {
    moneyArr = money;
    N = moneyArr.size(); // ์ง‘์˜ ๊ฐœ์ˆ˜ ์ €์žฅ
    vector<int> bitmap(N, 1); memset(memo, -1, sizeof(memo));
    int res = stillMoney(bitmap, 0);

    bitmap = vector<int>(N, 1); memset(memo, -1, sizeof(memo));
    res = max(res, stillMoney(bitmap, 1));
    return res;
}

 

๊ฒฐ๊ณผ

1. <์ ํ™”์‹ top-down>

 

2. <์ ํ™”์‹ bottom-up>

 

3. <์žฌ๊ท€ - ํšจ์œจ์„ฑ 0์ >

bitmap์œผ๋กœ ์ฒดํฌํ•  ํ•„์š” ์—†๋Š”๋ฐ ์ฒดํฌํ•ด์„œ ๊ทธ๋Ÿฐ ๋“ฏ ํ•˜๋‹ค.

๋ฐ˜์‘ํ˜•