Hello Ocean! ๐ŸŒผ

[์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œํ•ด๊ฒฐ์ „๋žต] 8์žฅ ๋™์  ๊ณ„ํš๋ฒ•_1 ๋ณธ๋ฌธ

Algorithm

[์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œํ•ด๊ฒฐ์ „๋žต] 8์žฅ ๋™์  ๊ณ„ํš๋ฒ•_1

bba_dda 2020. 4. 2. 12:22
๋ฐ˜์‘ํ˜•

๋™์  ๊ณ„ํš๋ฒ• = dynamic programming 

 

[๊ฐœ๋…]

๋ถ„ํ• ์ •๋ณต๊ณผ ๊ฐ™์ด ์ฒ˜์Œ ์ฃผ์–ด์ง„ ๋ฌธ์ œ๋“ค์„ ๋” ์ž‘์€ ๋ฌธ์ œ๋“ค๋กœ ๋‚˜๋ˆˆ ๋’ค, ์ž‘์€ ์กฐ๊ฐ๋“ค์„ ๊ณ„์‚ฐํ•˜๊ณ , ํ•ฉ์ณ์„œ ๋” ํฐ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋‹ต์„ ๊ณ„์‚ฐํ•ด๋‚ด๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

๋ถ„ํ•  ์ •๋ณต๊ณผ ๋‹ค๋ฅธ ์ ์€ '์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ'๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•ด์„œ ํ•œ ๋ฒˆ๋งŒ ๊ณ„์‚ฐํ•˜๊ฒŒ๋” ๋งŒ๋“ ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ(overlapping subproblem) : ๋ฌธ์ œ๋ฅผ ํ‘ธ๋Š”๋ฐ์— ๋‘ ๋ฒˆ ์ด์ƒ ๊ณ„์‚ฐ ๋˜๋Š” ๋ถ€๋ถ„๋ฌธ์ œ 

 

์™ผ์ชฝ : ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ x(๋‹จ์ˆœ ๋ถ„ํ•  ์ •๋ณต) / ์˜ค๋ฅธ์ชฝ : ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œo (๋™์  ๊ณ„ํš๋ฒ•)

์œ„์˜ ์‚ฌ์ง„์—์„œ๋Š” ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ๊ฐ€ ํ•œ ๊ฐœ ์ด์ง€๋งŒ, ๊นŠ์ด๊ฐ€ ๊นŠ์–ด์งˆ ๊ฒฝ์šฐ ์ง€์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค. 

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์ด ๋™์  ๊ณ„ํš๋ฒ•์ด๋‹ค.

 

[์˜ˆ์‹œ : ์ดํ•ญ๊ณ„์ˆ˜(์กฐํ•ฉ)]

์„œ๋กœ ๋‹ค๋ฅธ n๊ฐœ์˜ ์›์†Œ ์ค‘์— r๊ฐœ์˜ ์›์†Œ๋ฅผ ์ˆœ์„œ ์—†์ด ๊ณจ๋ผ๋‚ด๋Š” ๋ฐฉ๋ฒ•์˜ ์ˆ˜ 

์ด ๋ฌธ์ œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? => ์žฌ๊ท€ ํ˜ธ์ถœ์ด ๋ช‡ ๋ฒˆ์ด๋‚˜ ์ด๋ฃจ์–ด์ง€๋Š”์ง€ ๊ณ„์‚ฐ

int bino(int n, int r) {
	if (r==0 || n==r) return 1;
    return bino(n-1,r-1) + bino(n-1,r);
   }

bino(4,2)๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค๊ณ  ํ•  ๋•Œ, bino(2,1)์ด ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋œ๋‹ค. 

n๊ณผ r์˜ ์ˆซ์ž๊ฐ€ ์ปค์ง์— ๋”ฐ๋ผ ํ•จ์ˆ˜์˜ ์ค‘๋ณต ํ˜ธ์ถœ ํšŸ์ˆ˜๋Š” ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค. 

์—ฌ๊ธฐ์„œ n๊ณผ r์ด ์ •ํ•ด์ ธ ์žˆ์„ ๋•Œ, bino(n,r)์˜ ๊ฐ’์€ ์–ด๋–ค ๊ฒฝ์šฐ์—๋“  ํ•ญ์ƒ ๊ฐ™๋‹ค.

์ด ์ ์„ ์ด์šฉํ•ด์„œ ๊ฐ n,r์กฐํ•ฉ์— ๋Œ€ํ•œ ๊ฐ’๋“ค์„ ์ €์žฅํ•ด๋†“์œผ๋ฉด, ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ, ๋˜๋‹ค์‹œ ๊ณ„์‚ฐ๋˜์ง€ ์•Š๊ณ  ๋ฐฐ์—ด์— ์ €์žฅํ•ด๋†“์€ ๊ฐ’์„ ๊บผ๋‚ด์„œ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

(์ด์ „์— ๊ณ„์‚ฐ๋œ ๊ฒฝ์šฐ๊ฐ€ ์—†๋Š” ํ•จ์ˆ˜๋Š” ์ƒˆ๋กœ ๊ณ„์‚ฐํ•ด์„œ ๋ฐฐ์—ด์— ์ €์žฅํ•ด ๋†“์•„์•ผ ํ•œ๋‹ค)

 

[Memorization]

ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๋Š” ์žฅ์†Œ๋ฅผ ๋งŒ๋“ค์–ด๋‘๊ณ , ๊ณ„์‚ฐํ•œ ๊ฐ’์„ ์ €์žฅํ•ด ๋‘์—ˆ๋‹ค๊ฐ€ ์žฌํ™œ์šฉํ•˜๋Š” ์ตœ์ ํ™” ๊ธฐ๋ฒ• 

memorization์„ ์ด์šฉํ•ด ์œ„์˜ binoํ•จ์ˆ˜๋ฅผ ์ˆ˜์ •ํ•ด๋ณด์ž.

int cache[30][30];
int bino2(int n, int r){
	if (r==0 || n==r) return 1;
    //์ด์ „์— ์ €์žฅ๋œ ๊ฐ’์ด ์žˆ์œผ๋ฉด
    if (cache[n][r] != -1)
    	return cache[n][r]
    //์ด์ „์— ์ €์žฅ๋œ ๊ฐ’์ด ์—†์œผ๋ฉด ์ƒˆ๋กœ ๊ณ„์‚ฐ ํ›„ ์ €์žฅ
    return cache[n][r]=bino2(n-1,r-1) + bino2(n-1,r);
}

memorization์„ ์ ์šฉํ•˜๋ฉด ์†๋„์˜ ํ–ฅ์ƒ์„ ๊พ€ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

[Memorization์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ]

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ์˜ ํ•จ์ˆ˜๋Š” ํ•จ์ˆ˜์˜ ์ž…๋ ฅ ์™ธ์—๋„ ์ „์—ญ๋ณ€์ˆ˜, ์ž…๋ ฅํŒŒ์ผ, ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ ๋“ฑ์— ๋”ฐ๋ผ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž…๋ ฅ์ด ๊ฐ™๋‹ค๊ณ  ํ•ญ์ƒ ๊ฐ™์€ ๊ฐ’์ด ์ถœ๋ ฅ๋˜์ง€ ์•Š๋Š”๋‹ค. 

int counter = 0;
int count(){
	return counter++;
}

countํ•จ์ˆ˜๋Š” ์ „์—ญ๋ณ€์ˆ˜์ธ counter์„ ์ถœ๋ ฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ž…๋ ฅ์„ ์ „ํ˜€ ๋ฐ›์ง€ ์•Š์œผ๋ฉด์„œ๋„ ๋งค๋ฒˆ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

๋ฐ˜๋ฉด์— ์œ„์—์„œ ์ž‘์„ฑํ–ˆ๋˜ bino(), bino2()๋Š” ์ž…๋ ฅ์ด ๊ฐ™์œผ๋ฉด ํ•ญ์ƒ ์ถœ๋ ฅ์ด ๊ฐ™์€ ํ•จ์ˆ˜์ด๋‹ค.

 

์ฐธ์กฐ์  ํˆฌ๋ช…์„ฑ (referential transparency) : ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์ด ๊ทธ ์ž…๋ ฅ ๊ฐ’๋งŒ์œผ๋กœ ๊ฒฐ์ •๋˜๋Š”์ง€์˜ ์—ฌ๋ถ€ 

 

memorization์€ ์ฐธ์กฐ์  ํˆฌ๋ช…ํ•จ์ˆ˜์— ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

count()์ฒ˜๋Ÿผ ์ž…๋ ฅ์ด ๊ฐ™์€๋ฐ๋„ ์™ธ๋ถ€ ์š”์†Œ์— ๋”ฐ๋ผ ์ถœ๋ ฅ์ด ๋‹ฌ๋ผ์ง„๋‹ค๋ฉด, ๋ฏธ๋ฆฌ ์ €์žฅํ•ด๋‘˜ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

[memorization ๊ตฌํ˜„ ํŒจํ„ด]

 

1. ํ•ญ์ƒ ๊ธฐ์ €์‚ฌ๋ก€๋ฅผ ์ œ์ผ ๋จผ์ € ์ฒ˜๋ฆฌํ•œ๋‹ค.

2. ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์˜ ๋ฒ”์œ„๋ฅผ ๊ณ ๋ คํ•˜์—ฌ cache ๊ฐ’์„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค

(memset()์„ ์ด์šฉํ•˜๋ฉด ๋‹ค์ค‘ for๋ฌธ์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํŽธ๋ฆฌํ•˜๋‹ค. ํ•˜์ง€๋งŒ 0,-1๊ณผ ๊ฐ™์€ ์ œํ•œ์ ์ธ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)

3. ret์€ cache[a][b]์— ๋Œ€ํ•œ ์ฐธ์กฐํ˜•(reference)์ž„์„ ๊ธฐ์–ตํ•˜์ž.

(ret์˜ ๊ฐ’์„ ๋ฐ”๊พธ๋ฉด cache[a][b]๋„ ๊ฐ™์ด ๋ฐ”๋€œ)

int cache[2500][2500] //a์™€ b์˜ ๋ฒ”์œ„์— ๋”ฐ๋ผ ํฌ๊ธฐ ์กฐ์ ˆํ•˜๊ธฐ
int someFunction(int a, int b){
	if (...) return ... //๊ธฐ์ €์‚ฌ๋ก€ ์ฒ˜๋ฆฌ
    int& ret = cache[a][b];
    if (ret != -1) return ret; //์ด์ „์— ๊ตฌํ•œ ์ ์ด ์žˆ์„ ๋•Œ
    
    ... //์ด์ „์— ๊ตฌํ•œ์ ์ด ์—†์„ ๋•Œ, ์ƒˆ๋กœ ๋‹ต ๊ณ„์‚ฐ
    
    return ret;
}
int main() {
	memset(cache, -1, sizeof(cache)); //memory ์ดˆ๊ธฐํ™”
    ...
}

 

[memorization ์‹œ๊ฐ„ ๋ณต์žก๋„ ๋ถ„์„]

๊ฐ ์ž…๋ ฅ์— ๋Œ€ํ•ด ํ•จ์ˆ˜๋ฅผ ์ฒ˜์Œ ํ˜ธ์ถœํ•  ๋•Œ์™€ ๊ทธ ๋‹ค์Œ์œผ๋กœ ํ˜ธ์ถœํ•  ๋•Œ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์ด ๋‹ฌ๋ผ์ง„๋‹ค.

๋”ฐ๋ผ์„œ ๋ณต์žกํ•˜์ง€๋งŒ, ์ฃผ๋จน๊ตฌ๊ตฌ์‹์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ณ„์‚ฐํ•ด๋ณด์ž

 

(์กด์žฌํ•˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ์ˆ˜) * (ํ•œ ๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ํ’€ ๋•Œ ํ•„์š”ํ•œ ๋ฐ˜๋ณต๋ฌธ์˜ ์ˆ˜ํ–‰ ํšŸ์ˆ˜)

 

bino2()์˜ ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด๋ณด์ž.

r์˜ ์ตœ๋Œ€์น˜๋Š” n์ด๊ธฐ ๋•Œ๋ฌธ์— bino2()๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ ๋งŒ๋‚  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ์ˆ˜๋Š” ์ตœ๋Œ€ O(n^2)์ด๋‹ค 

๊ฐ ๋ถ€๋ถ„๋ฌธ์ œ ๊ณ„์‚ฐ์— ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์€ ๋ฐ˜๋ณต๋ฌธ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— O(1)์ด๋‹ค.

๋”ฐ๋ผ์„œ bino2()์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(n^ 2)*O(n) = O(n^2)์ด๋‹ค.

์ด ๋ฐฉ๋ฒ•์€ ํ•ญ์ƒ ์ •ํ™•ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๊ฐ„๋‹จํžˆ ๊ณ„์‚ฐํ•ด ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. 

์˜ˆ๋ฅผ๋“ค์–ด ๋ชจ๋“  ๋ถ€๋ถ„ ๋ฌธ์ œ ์ค‘์— ์ผ๋ถ€๋ถ„๋งŒ ๊ณ„์‚ฐํ•ด๋„ ๋‹ต์„ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋ผ๋ฉด ์‹ค์ œ ์ˆ˜ํ–‰์‹œ๊ฐ„์ด ์‹๋ณด๋‹ค ํ›จ์”ฌ ์ ์„ ๊ฒƒ์ด๋‹ค. 

 

๋ฐ˜์‘ํ˜•