๊ด€๋ฆฌ ๋ฉ”๋‰ด

๐˜š๐˜ญ๐˜ฐ๐˜ธ ๐˜ฃ๐˜ถ๐˜ต ๐˜ด๐˜ต๐˜ฆ๐˜ข๐˜ฅ๐˜บ

[์•Œ๊ณ ๋ฆฌ์ฆ˜] ๋™์ ๊ณ„ํš๋ฒ•(Dynamic Programming) ๋ณธ๋ฌธ

์•Œ๊ณ ๋ฆฌ์ฆ˜

[์•Œ๊ณ ๋ฆฌ์ฆ˜] ๋™์ ๊ณ„ํš๋ฒ•(Dynamic Programming)

.23 2021. 7. 9. 16:06

'์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์ž๋ฃŒ ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ with C++' ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

1. ๋™์  ๊ณ„ํš๋ฒ• ; dynamic programming

1.1 ๊ฐœ๋…

๋ถ„ํ•  ์ •๋ณต ํŒจ๋Ÿฌ๋‹ค์ž„ ๊ฐœ๋…์„ ํ™•์žฅํ•œ ๊ฒƒ์œผ๋กœ, ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ„์–ด ํ‘ธ๋Š” ๋ฌธ์ œ๋ฅผ ์ผ์ปซ๋Š” ๋ง์ด๋‹ค. ์–ธ๋œป ๋ฌธ์ œ๋ฅผ ๋ณด๋ฉด ๋น„์Šทํ•˜๋‹ค ์ƒ๊ฐ๋  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ถ„ํ•  ์ •๋ณต๊ณผ ๊ตฌ๋ถ„๋˜๋Š” ๋™์  ๊ณ„ํš๋ฒ•๋งŒ์˜ ํŠน์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

1. ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ(overlapping subproblem)

2. ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ(optimal substructure)

 

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์†์„ฑ์„ ๋งŒ์กฑํ•ด์•ผ ๋™์  ๊ณ„ํš๋ฒ•์„ ํ†ตํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์ „์ฒด ๋ฌธ์ œ๊ฐ€ ๋…๋ฆฝ์ ์ธ ๋ถ€๋ถ„ ๋ฌธ์ œ๋กœ ๋‚˜๋‰˜๋Š” ๋ถ„ํ•  ์ •๋ณต ๋ฌธ์ œ์™€ ๋‹ฌ๋ฆฌ ๋™์  ๊ณ„ํš๋ฒ•์—์„œ๋Š” ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋“ฑ์žฅํ•œ๋‹ค. ๋˜ํ•œ ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ ธ ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ์ตœ์ ์˜ ๋‹ต์„ ์ด์šฉํ•˜์—ฌ ์ „์ฒด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ตœ์ ์˜ ๋‹ต์„ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.


๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด์ž. ์žฌ๊ท€ ํ•จ์ˆ˜๋ฅผ ๋ฐฐ์šธ ๋•Œ ๊ฐ€์žฅ ๋จผ์ € ๋ฐฐ์šฐ๋Š” ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ๋– ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

{ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... } ์™€ ๊ฐ™์€ ์ˆœ์„œ๋ฅผ ๊ฐ€์ง€๋Š” ์ˆ˜์—ด์„ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์ด๋ผ๊ณ  ํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š” ๊ทœ์น™์„ ์ฐพ์•„๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

F(0) = 0

F(1) = 1

..

F(n) = F(n - 1) + F(n - 2)

 

F(n)์€ ์ด์ „ ์›์†Œ ๋‘ ๊ฐœ(F(n-1), F(n-2))์— ์˜ํ•ด ๊ฒฐ์ •๋˜๊ณ , F(n) = F(n - 1) + F(n - 2) ์™€ ๊ฐ™์ด ํ‘œํ˜„๋˜๋Š” ์ˆ˜์‹์€ ์ด ์ˆ˜์—ด์˜ ์žฌ๊ท€ ๊ด€๊ณ„(recurrence relation) ๊ฐ€ ๋œ๋‹ค. 

F(5)๋ฅผ ๊ตฌํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์—์„œ F(5) ๊ณ„์‚ฐํ•˜๊ธฐ

์œ„์˜ ์žฌ๊ท€ ํŠธ๋ฆฌ์—์„œ F(4) = F(3) + F(2)์ด๊ณ , F(3) = F(2) + F(1) ์ด๊ธฐ ๋•Œ๋ฌธ์— F(2)๋Š” F(4)์™€ F(3)์„ ๊ตฌํ•˜๋Š” ๊ณผ์ •์—์„œ ์—ฌ๋Ÿฌ ๋ฒˆ ๋“ฑ์žฅํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ F(2)๋Š” F(4)๋ฅผ ๊ตฌํ•˜๋Š” ๊ณผ์ •์—์„œ๋„, F(3)์„ ๊ตฌํ•˜๋Š” ๊ณผ์ •์—์„œ๋„ ์‚ฌ์šฉ์ด ๋œ๋‹ค. F(4)๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด ์ด์ „์— ๊ตฌํ•ด๋‘์—ˆ์„ F(2)๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ๋ฅผ ๋งŒ์กฑํ•œ๋‹ค.

 

1.2 ์ ‘๊ทผ๋ฐฉ๋ฒ•

์ ‘๊ทผ ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ ์บ์‹œ(cache)์— ๊ธฐ๋กํ•˜๋Š” ํ•˜ํ–ฅ์‹ ์ ‘๊ทผ๋ฐฉ๋ฒ•(top-down approach)๊ณผ ํ‘œ๋ฅผ ๋งŒ๋“ค์–ด ์ €์žฅํ•˜๋Š” ์ƒํ–ฅ์‹ ์ ‘๊ทผ๋ฐฉ๋ฒ•(bottom-up approach)์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.

 

1.2.1 ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ; ํ•˜ํ–ฅ์‹ ์ ‘๊ทผ ๋ฐฉ๋ฒ•

๋ฉ”๋ชจ๋ฅผ ํ•œ๋‹ค๋Š” ๋œป์˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(memoization)์€ ๊ฐ ๋‹จ๊ณ„๋งˆ๋‹ค ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ํ•ด๋‹ต์„ ์ฐพ์œผ๋ฉด ๋ฐฐ์—ด ๊ตฌ์กฐ์˜ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค. ์บ์‹œ์— ๊ฐ’์ด ์ €์žฅ๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜์—ฌ ์ €์žฅ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ €์žฅ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์‰ฝ๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ์žฌ๊ท€ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์œ„์—์„œ๋ถ€ํ„ฐ ๊ณ„์‚ฐํ•ด ๋‚˜๊ฐ€๋Š” ๋ฐฉ์‹์ด ์ด์— ํ•ด๋‹นํ•œ๋‹ค. 

 

1.2.2 ํƒ€๋ทธ๋ ˆ์ด์…˜ ; ์ƒํ–ฅ์‹ ์ ‘๊ทผ ๋ฐฉ๋ฒ•

ํ…Œ์ด๋ธ”์— ์ •๋ฆฌํ•œ๋‹ค๋Š” ์˜๋ฏธ์˜ ํƒ€๋ทธ๋ ˆ์ด์…˜(tabulation)์€ ๋ชจ๋“  ๋ถ€๋ถ„ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๋‹ต์„ ํ‘œ์— ์ €์žฅํ•œ ํ›„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ๋ฐ˜๋ณต๋ฌธ์„ ํ†ตํ•ด ๋ถ€๋ถ„ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๋‹ต์„ ์ €์žฅํ•ด๋‚˜๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์ด ํšจ์œจ์ ์ด๊ณ , ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์ƒํƒœ๋ฅผ ๊ธฐ๋กํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž„์˜์˜ ์—ฌ๋Ÿฌ ์ƒํƒœ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์‰ฝ๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.


ํƒ€๋ทธ๋ ˆ์ด์…˜์„ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ธด ํ•˜์ง€๋งŒ, ๋ฉ”๋ชจ์ด์ œ์ด์…˜์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๋ฌธ์ œ๋Š” ํƒ€๋ทธ๋ ˆ์ด์…˜์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ๋ฐ˜๋Œ€ ์—ญ์‹œ ๊ฐ€๋Šฅํ•˜๋‹ค. ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด์ž.

์šฐ๋ฆฌ๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์•Œ๊ณ  ์žˆ๋Š” ์žฌ๊ท€๋ฅผ ์ด์šฉํ•œ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

int Fibonacci(int n) {
    if(n < 2) return n;
    return Fibonacci(n - 1) + Fibonacci(n - 2);
}

์œ„์˜ ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค๋ฉด, n์— ์กฐ๊ธˆ๋งŒ ํฐ ์ˆ˜๊ฐ€ ๋“ค์–ด๊ฐ€๋„ ๋‹ต์ด ๋‚˜์˜ค๋Š” ๋ฐ ๊ต‰์žฅํžˆ ์˜ค๋ž˜๊ฑธ๋ฆฌ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ์œ„ ํ•จ์ˆ˜์˜ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ O(2^n)์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์•ž์„œ ์„ค๋ช…ํ•œ ๋‘ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•˜์—ฌ ํ’€์–ด๋ณด๋„๋ก ํ•œ๋‹ค.

 

#1. ๋ฉ”๋ชจ์ด์ œ์ด์…˜

#define MAX 101

vector<int> memo(MAX, -1);

int DP(int num) {
    if(num < 2) return num;		// ๊ธฐ์ €์ƒํƒœ ์„ค์ •
    if(memo[num] > 0) return memo[num];
    
    int result = DP(n - 1) + DP(n - 2);
    memo[num] = result;
    return result;
}

 

#2. ํƒ€๋ทธ๋ ˆ์ด์…˜

int DP(int num) {
    vector<int> table(num + 1, 0);
    table[1] = 1;		// ๊ธฐ์ €์ƒํƒœ ์„ค์ •
    
    for(int i = 2; i <= num; i++) {
        table[i] = table[i - 1] + table[i - 2];
    }
    
    return table[num];
}

 

Comments