[์•Œ๊ณ ๋ฆฌ์ฆ˜] ๋™์  ๊ณ„ํš๋ฒ•, ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด๋ž€?

2021. 11. 27. 10:30ใ†Programming/Algorithms

 

๋™์  ๊ณ„ํš๋ฒ• ์ค‘ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ์šฉํ•˜๋Š” ๋ฌธ์ œ๋“ค์ด ์ฐธ ๋งŽ์•˜๋Š”๋ฐ, 

๋ฌด์Šจ ์†Œ๋ฆฌ์ธ์ง€ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์˜ค๋Š˜ ๊ฐ์žก๊ณ  ์กฐ์‚ฌํ•ด๋ณด์•˜๋‹ค. ^_^

 

 

 

 

 

1. ๋™์  ๊ณ„ํš๋ฒ•์ด๋ž€?

 

  ๋™์  ๊ณ„ํš๋ฒ• (dynamic programming): ์ฒ˜์Œ ์ฃผ์–ด์ง„ ๋ฌธ์ œ๋“ค์„ ๋ถ„ํ• ํ•˜๊ณ , ์ด๋กœ๋ถ€ํ„ฐ ๋ณธ ๋ฌธ์ œ์— ๊ด€ํ•œ ๋‹ต์„ ๋„์ถœํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ๋ฒ•์ด๋‹ค. ํŠนํžˆ ๋ถ€๋ถ„ ๋ฌธ์ œ๋“ค์˜ ์ˆ˜๊ฐ€ ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค. ๋™์  ๊ณ„ํš๋ฒ•์€ ์—ฌ๋Ÿฌ ๋ฌธ์ œ ํ•ด๊ฒฐ์— ์‚ฌ์šฉ๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ๊ณ„์‚ฐํ•˜๋Š” ๋Œ€์‹ , ํ•œ ๋ฒˆ๋งŒ ๊ณ„์‚ฐํ•˜๊ณ  ์ด๋ฅผ ์žฌํ™œ์šฉํ•˜์—ฌ ์†๋„๋ฅผ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค๋Š” ์ ์—์„œ ๋ถ„ํ•  ์ •๋ณต๋ฒ•๊ณผ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•˜์—ฌ ๊ฐ ๋ฌธ์ œ์˜ ๋‹ต์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋ฏธ ๊ณ„์‚ฐ๋œ ๊ฐ’์„ ์ €์žฅํ•ด๋‘๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ์žฅ์†Œ๋ฅผ ์บ์‹œ(cache)๋ผ๊ณ  ํ•˜๋ฉฐ, ๋‘ ๋ฒˆ ์ด์ƒ ๊ณ„์‚ฐ๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„๋ฌธ์ œ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. 

 

 

 

- ๊ฐ ๋ถ€๋ถ„ ๋ฌธ์ œ๋“ค์ด ์„œ๋กœ ์—ฐ๊ด€์ด ์—†์„ ๋•Œ

-> ๋‹จ์ˆœํ•œ ์žฌ๊ท€ ํ˜ธ์ถœ๋กœ ๋ฌธ์ œ ํ•ด๊ฒฐ

-> ๋ถ„ํ•  ์ •๋ณต๋ฒ•

 

- But ๋‚˜๋ˆ ์ง„ ๋ฌธ์ œ๋“ค์ด ๊ฐ™์€ ๋ถ€๋ถ„ ๋ฌธ์ œ๋“ค์— ์ค‘๋ณต๋˜์–ด ์˜์กดํ•  ๋•Œ

-> ๋ถ„ํ• ์˜ ๊นŠ์ด๊ฐ€ ๊นŠ์–ด์งˆ์ˆ˜๋ก ์ค‘๋ณต ํšŸ์ˆ˜ ์ง€์ˆ˜์  ์ฆ๊ฐ€ (์กฐํ•ฉ ํญ๋ฐœ)

-> ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๊ณ ์•ˆ๋œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ : ๋™์  ๊ณ„ํš๋ฒ•

 

 

 

 

 

2. ๋ฉ”๋ชจ์ด์ œ์ด์…˜(memoization)์ด๋ž€?

 

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

 - ๋™์ผํ•œ ๊ณ„์‚ฐ์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ•  ๊ฒฝ์šฐ, ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ํ†ตํ•˜์—ฌ ์ค‘๋ณต ๊ณ„์‚ฐ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 - ๋ฉ”๋ชจ๋ฆฌ๋ผ๋Š” ๊ณต๊ฐ„ ๋น„์šฉ์„ ํˆฌ์ž…ํ•˜์—ฌ, ๊ณ„์‚ฐ์— ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„ ๋น„์šฉ์„ ์ค„์ด๋Š” ๋ฐฉ์‹์ด๋‹ค. 

 

 

 

 

 

3. ๋ฉ”๋ชจ์ด์ œ์ด์…˜์˜ ํ™œ์šฉ

 

// ์žฌ๊ท€ ํ˜ธ์ถœ์„ ํ†ตํ•œ ์ดํ•ญ ๊ณ„์ˆ˜์˜ ๊ณ„์‚ฐ

int bino(int n, int r) {
	if (r == 0 || n == r) {
		return 1;
		// ๊ธฐ์ € ์‚ฌ๋ก€
	}
	else {
		return bino(n - 1, r - 1) + bino(n - 1, r);
		// ํ•จ์ˆ˜์˜ ์ค‘๋ณต ํ˜ธ์ถœ ํšŸ์ˆ˜๋Š” n๊ณผ r์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€
	}
}


// ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ํ†ตํ•œ ์ดํ•ญ ๊ณ„์ˆ˜์˜ ๊ณ„์‚ฐ

int cache[30][30]; // -1๋กœ ์ดˆ๊ธฐํ™”
int bino2(int n, int r) {
	if (r == 0 || n == r) {
		return 1;
		// ๊ธฐ์ € ์‚ฌ๋ก€
	}

	if (cache[n][r] != -1) {
		return cache[n][r];
		// -1์ด ์•„๋‹ˆ๋ผ๋ฉด ์ด๋ฏธ ๊ณ„์‚ฐ๋œ ๊ฐ’์ด ์žˆ๋‹ค๋Š” ๋œป!
	}

	else {
		cache[n][r] = bino2(n - 1, r - 1) + bino2(n - 1, r);
		return cache[n][r];
	}
}

 

 

 

// ๊ท€์—ฝ๊ณ  ์žฌ๋ฏธ์žˆ๋Š” ๋‹ฌํŒฝ์ด ๋ฌธ์ œ์—์„œ๋„ cache๋ฅผ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค! :)


int n = 0;
int m = 0;
int cache [MAX_N] [2 * MAX_N + 1];

int climb(int days, int climbed) {
	if (days == m) {
		return climbed >= n ? 1 : 0;
	}

	int& ret = cache[days][climbed];
	if (ret != -1) {
		return ret;
	}
	
	ret = climb(days + 1, climbed + 1) + climb(days + 1, climbed + 2);
	return ret;
}


// ์žฅ๋งˆ๊ฐ€ ์ฐพ์•„์™”๋‹ค!
// ์—ฌ๋ฆ„ ์žฅ๋งˆ๋กœ ์ธํ•ด ๋น„๊ฐ€ ์˜ฌ ํ™•๋ฅ ์ด 50% -> 75%

int climb2(int days, int climbed) {
	if (days == m) {
		return climbed >= n ? 1 : 0;
	}

	int& ret = cache[days][climbed];
	if (ret != -1) {
		return ret;
	}

	ret = 0.25*climb2(days + 1, climbed + 1) + 0.75*climb2(days + 1, climbed + 2);
	return ret; // ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ์•„๋‹Œ, ํ™•๋ฅ ์„ return ํ•œ๋‹ค. 
}

 

 

 

 

 

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

 

- ํšจ์œจ์ ์ธ ๋™์  ๊ณ„ํš๋ฒ• ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ์•„์ฃผ ์ค‘์š”ํ•œ ์กฐ๊ฑด์ด๋‹ค. 

- ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ๊ฐ€ ์„ฑ๋ฆฝํ•  ๊ฒฝ์šฐ, ๊ฐ ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๋งŒ์œผ๋กœ ์ „์ฒด ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค. 

- ์ง€๊ธˆ๊นŒ์ง€์˜ ์„ ํƒ๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ๊ฐ ๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ์ตœ์ ์œผ๋กœ ํ’€๊ธฐ๋งŒ ํ•˜๋ฉด, ์ „์ฒด ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๋„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. 

- ๋งŽ์€ ๋ฌธ์ œ์—์„œ ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ๋Š” ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ๋ช…์ด ํ•„์š”ํ•  ๊ฒฝ์šฐ ๊ท€๋ฅ˜๋ฒ•, ํ˜น์€ ๋Œ€์šฐ๋ฅผ ํ™œ์šฉํ•œ๋‹ค. 

 

 

 ex) ์„œ์šธ์—์„œ ๋ถ€์‚ฐ์œผ๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๊ฐ€ ๋Œ€์ „์„ ์ง€๋‚œ๋‹ค. 

ํ•ด๋‹น ๊ฒฝ๋กœ๋ฅผ (์„œ์šธ, ๋Œ€์ „), (๋Œ€์ „, ๋ถ€์‚ฐ)์œผ๋กœ ๋‚˜๋ˆŒ ๋•Œ, ๊ฐ๊ฐ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์–ป์œผ๋ฉด ์ „์ฒด ๊ฒฝ๋กœ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค. 

์ด์™€ ๊ฐ™์ด ๊ฐ ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๊ฐ€ ์ „์ฒด ๋ฌธ์ œ์˜ ์ตœ์ฒ™ํ•ด๋กœ ์ด์–ด์งˆ ๋•Œ, ์ด๋ฅผ ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ๋ฅผ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•œ๋‹ค. 

 

 

 

 

5. ์ตœ์ ํ™” ๋ฌธ์ œ ๋™์  ๊ณ„ํš๋ฒ• TIP

 

1. ๋ชจ๋“  ๋‹ต์„ ๋งŒ๋“ค์–ด๋ณด๊ณ , ๊ทธ ์ค‘์—์„œ ์ตœ์ ํ•ด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์™„์ „ ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ค๊ณ„ํ•œ๋‹ค.

2. ์ „์ฒด ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๊ณ , ์•ž์œผ๋กœ ๋‚จ์€ ์„ ํƒ๋“ค์— ํ•ด๋‹นํ•˜๋Š” ๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋ถ€๋ถ„ ๋ฌธ์ œ์˜ ์ •์˜๋ฅผ ๋ณ€ํ™˜ํ•œ๋‹ค.

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

- ๊ฐ€๋Šฅํ•œ ํ•œ ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ๋งŽ์ด ๋งŒ๋“ ๋‹ค. ์ž…๋ ฅ์˜ ์ข…๋ฅ˜๊ฐ€ ์ค„์–ด๋“ค์ˆ˜๋ก ๋” ๋งŽ์€ ๋ถ€๋ถ„ ๋ฌธ์ œ๊ฐ€ ์ค‘๋ณต๋˜๊ณ , ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ตœ๋Œ€ํ•œ ํšจ์œจ์ ์œผ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

4. ์ž…๋ ฅ์ด ๋ฐฐ์—ด์ด๊ฑฐ๋‚˜ ๋ฌธ์ž์—ด์ด๋ผ๋ฉด, ์ ์ ˆํ•œ ๋ณ€ํ™˜์„ ํ†ตํ•˜์—ฌ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. 

5. ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ์šฉํ•œ๋‹ค. 

 

 

 

 

 

 

์ถœ์ฒ˜: 

- ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋Œ€ํšŒ์—์„œ ๋ฐฐ์šฐ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ ํ•ด๊ฒฐ ์ „๋žต (๊ตฌ์ข…๋งŒ)

- https://namu.wiki/w/%EB%A9%94%EB%AA%A8%EC%9D%B4%EC%A0%9C%EC%9D%B4%EC%85%98

- https://ssminji.github.io/2020/02/05/the-cake-thief/

- https://kamang-it.tistory.com/entry/AlgorithmDynamic-Programming%EB%8F%99%EC%A0%81%EA%B3%84%ED%9A%8D%EB%B2%95%EB%8B%A4%EC%9D%B4%EB%82%98%EB%AF%B9-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EA%B3%BC-%EB%A9%94%EB%AA%A8%EC%9D%B4%EC%A0%9C%EC%9D%B4%EC%85%98memoization-%ED%83%80%EB%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98tabulation