๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿค– data structures & algorithms

Data Structures & Algorithms with Javascript : Advanced Algorithms

[์ด์ „ ๊ธ€]2024.07.29 - [๐Ÿค– data structures & algorithms] - Data Structures & Algorithms with Javascript : Searching Algorithms

 

Data Structures & Algorithms with Javascript : Searching Algorithms

[์ด์ „๊ธ€] 2024.07.28 - [๐Ÿค– data structures & algorithms] - Data Structures & Algorithms with Javascript : Sorting Algorithms (Advanced) Data Structures & Algorithms with Javascript : Sorting Algorithms (Advanced)2024.07.27 - [๐Ÿค– data structures & al

pyotato-dev.tistory.com

๐Ÿฅณ ๋“œ๋””์–ด Data Structures & Algorithms with JavaScript์˜ ๋งˆ์ง€๋ง‰ ์žฅ ์ง์ „์— ๋„๋‹ฌํ–ˆ๋‹ค.
๋งˆ์ง€๋ง‰ ์žฅ์—์„œ๋Š” dynamic programming (DP)๊ณผ greedy algorithms(ํƒ์š• ์•Œ๊ณ ๋ฆฌ์ฆ˜)์— ๋Œ€ํ•ด ๋‹ค๋ฃฌ๋‹ค.

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

๋ฐ˜๋ฉด ํƒ์š• ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ˜„์žฌ ๊ฐ€๋Šฅํ•œ ์ตœ์„ ์˜ ํ•ด๊ฒฐ์ฑ…(local optima)์„ ์ฐพ์•„์„œ ํ•ด๊ฒฐ์ฑ…์„ ๋ชจ์ƒ‰ํ•œ๋‹ค.
์ตœ์„ ์˜ ๋‹ต์„ ์ฐพ๋‹ค๋ณด๋ฉด ๊ฒฐ๋ก ์ ์œผ๋กœ ์ตœ์ƒ์˜ ํ•ด๊ฒฐ์ฑ…(global optimum)์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.
ํƒ์š•์ด๋ผ๋Š” ๋ง์€ ํ˜„์žฌ ํ•ด๊ฒฐ์ฑ… ์ค‘ ๊ฐ€์žฅ ์™„๋ฒฝํ•œ ํ•ด๊ฒฐ์ฑ…์„ ๊ณจ๋ผ์„œ ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•ด์„œ ์–ป์€ ์ด๋ฆ„์ด๋‹ค.

์•„์ง ๋‘๋ฃจ๋ญ‰์‹คํ•œ ๊ฐœ๋… ๊ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋“ค์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์‚ดํŽด๋ณด์ž! 

Dynamic Programming

์žฌ๊ท€์ ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ฉด ๊น”๋”ํ•œ ํ’€์ด๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋น„ํšจ์œจ์ ์ด๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ํฌํ•จํ•œ ๋งŽ์€ ์–ธ์–ด๋“ค์€ ํšจ์œจ์ ์œผ๋กœ ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฃจ์ง€ ๋ชปํ•œ๋‹ค.

๋Œ€์‹  DP๋ฅผ ํ™œ์šฉํ•ด ์žฌ๊ท€์  ํ’€์ด๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค.

DP๋Š” ๋ฌธ์ œ๋ฅผ ์ชผ๊ฐ  ๊ฐ ๊ฒฐ๊ณผ ๊ฐ’๋“ค์„ ์ฃผ๋กœ ๋ฐฐ์—ด๋กœ ๋œ ํ‘œ๋กœ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ’€์ด๋ฅผ ํ•œ๋‹ค.

 

DP๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์˜ˆ์‹œ๋“ค์„ ์‚ดํŽด๋ณด์ž.

ํ”ผ๋ณด๋‚˜์น˜์ˆ˜์—ด 

ํ”ผ๋ณด๋‚˜์น˜์ˆ˜์—ด์„ dp๋กœ ๊ตฌํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ดํŽด๋ณด์ž.

 

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆ˜๋ฅผ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ด์ „ ๋‘ ๊ฐ’์„ ๋”ํ•œ ๊ฐ’์ด ๋‹ค์Œ ๊ฐ’์ด ๋˜๋Š” ์ˆ˜์—ด์ด๋‹ค.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55...

 

์žฌ๊ท€์ ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

function recurFib(n){
	if(n<2){
    	return n;
    } else {
    	return recurFib(n-1) + recurFib(n-2);
    }
}

print(recurFib(10);

 

์žฌ๊ท€์ ์œผ๋กœ ํ”ผ๋ณด๋‚˜์น˜์ˆ˜์—ด์„ ๊ตฌํ•˜๋Š” ๊ฑด ๋งค์šฐ ๋น„ํšจ์œจ์ ์ด๋‹ค. ๋‹ค์Œ์€ ์žฌ๊ท€์ ์œผ๋กœ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ๊ตฌํ•  ๋•Œ ์ƒ์„ฑ๋˜๋Š” ํŠธ๋ฆฌ ํ˜•ํƒœ๋‹ค.

๊ฐ™์€ ๊ฐ’์ด ์—ฌ๋Ÿฌ ๋ฒˆ ์žฌ์—ฐ์‚ฐ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋ฏธ ๊ณ„์‚ฐํ–ˆ๋˜ ๊ฐ’๋“ค์€ ์ €์žฅํ•ด์„œ ์žฌ์—ฐ์‚ฐ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข€ ๋” ํšจ์œจ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋  ๊ฑฐ ๊ฐ™๋‹ค.

DP์— ๋” ๊ฐ€๊นŒ์šด ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•ด ๋ณด์ž.

 

์ด์ „์— ๋งํ–ˆ๋“ฏ์ด, DP๋Š” ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•œ ๊ฐ€์žฅ ๋‹จ์ˆœํ•œ sub-problem์—์„œ ์‹œ์ž‘ํ•ด์„œ ๊ทธ ํ•ด๊ฒฐ์ฑ…์œผ๋กœ ๋” ๋ณต์žกํ•œ ๋ฌธ์ œ๋“ค์„ ํ’€์–ด๊ฐ€๋ฉฐ ์ •๋‹ต์„ ์ฐพ๋Š” ๋ฐฉ์‹์ด๋‹ค. 

function dynFib(n) {
    let val = []; // ์ค‘๊ฐ„ ์ค‘๊ฐ„ ๊ฒฐ๊ณผ ๊ฐ’์„ ์ €์žฅ
    for (let i = 0; i <= n; ++i) {
    	val[i] = 0; // 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ 
        }
    	if (n == 1 || n == 2) { 
        	return 1; // 1์ด๋‚˜ 2๋ฉด 0+1 ์ธ ๊ฒฝ์šฐ์ด๋ฏ€๋กœ ์ด๋ฅธ ์ข…๋ฃŒ
    	}
        else {
            val[1] = 1;
            val[2] = 2;
        for (let i = 3; i <= n; ++i) {
             val[i] = val[i-1] + val[i-2]; // ์ด์ „ ๋‘ ๊ฐ’๋“ค์„ ๋”ํ•ด์ค˜ ํ˜„์žฌ ์œ„์น˜์— ๋„ฃ์–ด์ค€๋‹ค.
        }
    	return val[n-1];
    }
}

 

์ด์ œ ํ•œ๋ฒˆ ๋‘ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋“ค์˜ ๋Ÿฐํƒ€์ž„ ๋น„๊ตํ•ด ๋ณด์ž. ํ™•์‹คํžˆ 20 ์ด์ƒ์˜ ํ”ผ๋ณด๋‚˜์น˜ ๊ฐ’์„ ๊ตฌํ•˜๊ณ ์ž ํ•  ๋•Œ DP๊ฐ€ ๋” ํšจ์œจ์ ์ด๋‹ค.

let start = new Date().getTime();
print(recurFib(20));
let stop = new Date().getTime();
print("recursive time - " + (stop-start) + "milliseconds"); 
print();
start = new Date().getTime();
print(dynFib(10));
stop = new Date().getTime();
print("dynamic programming time - " + (stop-start) + " milliseconds");

/**

// fib(20)์ธ ๊ฒฝ์šฐ
6765
recursive time - 1milliseconds

55
dynamic programming time - 1 milliseconds
*/

/**

// fib(30)์ธ ๊ฒฝ์šฐ
832040
recursive time - 14milliseconds

55
dynamic programming time - 0 milliseconds
*/

 

์ค‘๊ฐ„ ๊ฐ’์„ ์ €์žฅํ•˜์ง€ ์•Š๊ณ ๋„ dp์ฒ˜๋Ÿผ ํšจ์œจ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

function iterFib(n) {
    let last = 1;
    ;et nextLast = 1;
    ;et result = 1;
    for (let i = 2; i < n; ++i) {
              result = last + nextLast;
              nextLast = last;
              last = result;
    }
    return result; 
}

๋ฌธ์ž์—ด์˜ ์ตœ๋Œ€ ๊ณตํ†ต๋ถ€๋ถ„ ๊ตฌํ•˜๊ธฐ

DP๋ฅผ ํ™œ์šฉํ•ด ๋‘ ๋ฌธ์ž์—ด์ด ๊ณตํ†ต์ ์œผ๋กœ ๊ฐ–๋Š” ๋ฌธ์ž์—ด์„ ํšจ์œจ์ ์œผ๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, "raven"๊ณผ "havoc"๋ผ๋Š” ๋ฌธ์ž์—ด๋“ค์ด ์žˆ์„ ๋•Œ ๊ณตํ†ต ๋ฌธ์ž์—ด ์ค‘ ๊ฐ€์žฅ ๊ธด ๋ถ€๋ถ„์€ "av"๋‹ค.

 

DP๋กœ ํ’€์ดํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ดํŽด๋ณด๊ธฐ ์ „์— brute-force๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ดํŽด๋ณด์ž.

A์™€ B ๋ฌธ์ž์—ด์ด ์žˆ๋‹ค๋ฉด A์˜ ์ฒซ ์š”์†Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ B์˜ ๊ฐ ์š”์†Œ๋“ค๊ณผ ๋น„๊ตํ•˜์—ฌ ๋‹ค๋ฅธ ๊ฐ’์ด ์ƒ๊ธฐ๋ฉด A์˜ ๋‹ค์Œ ์š”์†Œ๋ถ€ํ„ฐ B์˜ ์š”์†Œ๋“ค๊ณผ ๋‹ค์‹œ ๋น„๊ตํ•˜๋ฉด์„œ ์‚ดํŽด๋ณด๋ฉด ๋œ๋‹ค. for ๋ฃจํ”„๋ฅผ ๋„๋Š” ํšŸ์ˆ˜๊ฐ€ ์ด๋ฏธ ๋„ˆ๋ฌด ๋งŽ์„ ๊ฑฐ๋ผ๊ณ  ์˜ˆ์ƒํ•œ๋‹ค.

 

DP๋Š” ์ด์ฐจ ๋ฐฐ์—ด๋กœ ์ผ์น˜ํ•˜๋Š” ๊ฐ’์˜ ๊ฐœ์ˆ˜๋ฅผ ์ €์žฅํ•˜์—ฌ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๋จผ์ € ์ด์ฐจ์› ๋ฐฐ์—ด์˜ ๋ชจ๋“  ๊ฐ’์„ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

๊ฐ™์€ ๊ฐ’์ด ๋ฐœ๊ฒฌ๋  ๋•Œ๋งˆ๋‹ค ๊ฐ ํ–‰๋ ฌ์˜ ๊ฐ’์„ 1์”ฉ ์ฆ๊ฐ€์‹œ์ผœ ์ค€๋‹ค. 

 

// ์ดˆ๊ธฐํ™”
     a b b c c 
d  0 0 0 0 0
b  0 0 0 0 0
b  0 0 0 0 0
c  0 0 0 0 0
c  0 0 0 0 0

     a b b c c
d  0 0 0 0 0
b  0 1 1 0 0
b  0 1 2 0 0
c  0 0 0 3 1
c  0 0 0 1 4

 

์ด์ œ ์ฝ”๋“œ๋กœ ์˜ฎ๊ฒจ๋ณด์ž!

const print = item => console.log(item);

function lcs(word1, word2){
	let max = 0;
    let index = 0;
    let lcsarr = Array.from(word1,(v,i)=>Array.from(word2,()=>0)); // ์ด์ฐจ์› ๋ฐฐ์—ด 0์œผ๋กœ ์ดˆ๊ธฐํ™”
    
    for(let i=0; i< word1.length; ++i){
    	for(let j=0; j <= word2.length;++j){
        	if(i==0 || j==0){
            	lcsarr[i][j] = 0;
            } else {
            	if(word1[i-1] == word2[j-1]){
                	lcsarr[i][j] = lcsarr[i-1][j-1]+1;
                } else {
                	lcsarr[i][j] = 0;
                }
            }
			if(max<lcsarr[i][j]){
            	max = lcsarr[i][j];
                index = i;
            }
        }
    }
	let str = '';
    if(max == 0){
    	return str;
    } else {
    	for(let i=index-max; i< max;++i){
        	str+=word2[i];
        }
		return str;
    
    }

}

print(lcs('abbcc','dbbcc')); // bb

knapsack ๋ฌธ์ œ

์•Œ๊ณ ๋ฆฌ์ฆ˜ ์—ฐ๊ตฌ์—์„œ ์ž์ฃผ ๋“ฑ์žฅํ•˜๋Š” knapsack ๋ฌธ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๋‹ค๋ฃฌ๋‹ค.

์˜จ๊ฐ– ๋ณด๋ฌผ๋“ค์ด ๊ฐ€๋“ ์ฐฌ ๊ธˆ๊ณ ๋ฅผ ํ„ธ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค๊ณ  ํ•˜์ž. ๊ทผ๋ฐ ์ด ๋งŽ์€ ๋ณด๋ฌผ๋“ค์„ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๊ฑด ์ž‘์€ ๋ฐฑํŒฉ๋ฟ์ด๋‹ค.

๊ฐ ์•„์ดํ…œ์€ ํฌ๊ธฐ์™€ ๊ฐ’์ด ๋‹ค๋ฅด๊ณ , ๋ฐฑํŒฉ์„ ์ฑ„์›Œ์„œ ๊ฐ€๋Šฅํ•œ ๊ฐ’์–ด์น˜๊ฐ€ ๋†’์€ ์•„์ดํ…œ์œผ๋กœ ์ฑ„์šฐ๊ณ  ์‹ถ๋‹ค๊ณ  ํ•˜์ž.

์•„์ดํ…œ.  ๐Ÿ’Ž    ๐Ÿ’      ๐ŸŽฎ      ๐Ÿ“บ

ํฌ๊ธฐ         3     4      7       8        9

๊ฐ’            4     5     10     11     13

๋ฐฑํŒฉ์˜ ํฌ๊ธฐ : 16๋ผ๊ณ  ํ•  ๋•Œ, ๐Ÿ’ + ๐Ÿ“บ = ํฌ๊ธฐ (7+9), ๊ฐ’(10+13)์„ ๊ฐ€์ ธ๊ฐ€๋Š” ๊ฒŒ ๊ฐ€์žฅ ์ด์ต์ด๋‹ค.

 

๋จผ์ € ์žฌ๊ท€์ ์œผ๋กœ ํ•ด๋‹น ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•ด ๋ณด์ž.

function max(a, b) { 
	return (a > b) ? a : b;
}
function knapsack(capacity, size, value, n) { 
	if (n == 0 || capacity == 0) {
		return 0; 
        }
	if (size[n-1] > capacity) {
		return knapsack(capacity, size, value, n-1);
	} else {
		return max(value[n-1] + knapsack(capacity-size[n-1], size, value, n-1), knapsack(capacity, size, value, n-1));
	} 
}
const value = [4,5,10,11,13];
const size = [3,4,7,8,9];
const capacity = 16;
const n = 5;
print(knapsack(capacity, size, value, n)); // 23

 

์žฌ๊ท€์ ์ธ ํ•ด๊ฒฐ๋ฒ•์€ ๊ฐ™์€ ์ผ€์ด์Šค๋“ค์„ ์žฌ๋ฐฉ๋ฌธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„ํšจ์œจ์ ์ด๋‹ค. DP๋กœ ๊ตฌํ˜„ํ•ด ๋ณด์ž.

function print(item){
    console.log(item);
}

function max(a, b) { 
    return (a > b) ? a : b;
}


function dKnapsack(capacity, size, value, n) { 
    let K = [];
    for (let i = 0; i <= n; i++) { 
        K[i] = [];
        for (let w = 0; w <= capacity; w++) { 
            if (i == 0 || w == 0) {
                K[i][w] = 0; 
            } else if (size[i-1] <= w) {
                K[i][w] = max(value[i-1] + K[i-1][w-size[i-1]], K[i-1][w]);
            } else {
                K[i][w] = K[i-1][w];
            }

        }
    }
    return K[n][capacity]; 
}

let values = [4,5,10,11,13];
let sizes = [3,4,7,8,9];
let capacity = 16;
let n = values.length;

print(dKnapsack(capacity, sizes, values, n)); // 23

 

Greedy Algorithms

๊ฑฐ์Šค๋ฆ„๋ˆ ์ฃผ๊ธฐ

!! ์ฑ…์€ cent๋กœ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์›ํ™”๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค!!

 

ํŽธ์˜์ ์—์„œ 1230์›์„ ๊ฑฐ์Šฌ๋Ÿฌ ๋ฐ›์•„์•ผ ํ•œ๋‹ค๊ณ  ํ•  ๋•Œ, ์ง์›์€ ์–ด๋–ป๊ฒŒ ์ตœ์†Œํ•œ์˜ ๋™์ „ ๊ฐœ์ˆ˜๋กœ ๊ฑฐ์Šฌ๋Ÿฌ์ค„ ์ˆ˜ ์žˆ์„๊นŒ?

10์›์งœ๋ฆฌ, 50์›์งœ๋ฆฌ, 100์›์งœ๋ฆฌ, 500์›์งœ๋ฆฌ ์ค‘์—์„œ ๊ณจ๋ผ์„œ ์ค„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

function print(item){
    console.log(item);
}

function makeChange(origAmt, coins) {
    let remainAmt = 0;

    if (origAmt % 500 < origAmt) {
        coins[3] = parseInt(origAmt / 500);
        remainAmt = origAmt % 500;
        origAmt = remainAmt;
    }
    if (origAmt % 100 < origAmt) {
        coins[2] = parseInt(origAmt / 100);
        remainAmt = origAmt % 100;
        origAmt = remainAmt;
    }
    if (origAmt % 50 < origAmt) {
        coins[1] = parseInt(origAmt / 50);
        remainAmt = origAmt % 50;
        origAmt = remainAmt;
    }
    coins[0] = parseInt(origAmt / 10);
}

function showChange(coins) {
    if (coins[3] > 0) {
        print("Number of 500 Won coins - " + coins[3] + " - " + coins[3] * 500);
    }
    if (coins[2] > 0) {
        print("Number of 100 Won coins - " + coins[2] + " - " + coins[2] * 100);
    }
    if (coins[1] > 0) {
        print("Number of 50 Won coins - " + coins[1] + " - " + coins[1] * 50);
    }
    if (coins[0] > 0) {
        print("Number of 10 Won coins - " + coins[0] + " - " + coins[0] * 10);
    }
}

let origAmt = 1230;
let coins = [];
makeChange(origAmt, coins);
showChange(coins);

/**
Number of 500 Won coins - 2 - 1000
Number of 100 Won coins - 2 - 200
Number of 10 Won coins - 3 - 30

*/

knapsack ๋ฌธ์ œ

์ด์ „์—๋Š” DP๋กœ knapsack ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ์žฌ๊ท€์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ดํŽด๋ดค๋‹ค.

์ด๋ฒˆ์—๋Š” ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๊ตฌํ˜„ํ•ด ๋ณด์ž.

๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ knapsack ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•  ๋•Œ ๋ฐฑํŒฉ ์•ˆ์— ๋„ฃ์„ ์•„์ดํ…œ๋“ค์ด ์—ฐ์†์ ์ธ ๋ฐ์ดํ„ฐ๋ผ๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค๋ฉด ์ฒœ์ด๋‚˜ ์‚ฌ๊ธˆ์ฒ˜๋Ÿผ ํ•˜๋‚˜ํ•˜๋‚˜ ์…€ ์ˆ˜ ์žˆ๋Š” ๋‹จ์œ„๋กœ ๋‚˜๋‰˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์ „์ฒด ๋ฉด์ ์ด๋‚˜ ๋ถ€ํ”ผ๋ฅผ ๊ตฌํ•˜๋“ฏ์ด ๋‹ค๋ฃจ๋ฉด ๋œ๋‹ค.

 

์ตœ์ ์˜ ํ•ด๋Š” ๋ฐฑํŒฉ ๊ณต๊ฐ„์ด ์—†๊ฑฐ๋‚˜ ์•„์ดํ…œ์ด ์†Œ์ง„๋  ๋•Œ๊นŒ์ง€ ๊ฐ€์žฅ ๋†’์€ ๊ฐ’๋“ค์„ ๋ฐฑํŒฉ์— ๋„ฃ๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋‹ค์Œ์—๋Š” ๊ฐ€๋Šฅํ•œ ๊ฐ’์ด ๋†’์€ ์•„์ดํ…œ์„ ๋„ฃ๊ณ , ์ด ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์—ฐ์†์ ์ธ ๋ฐ์ดํ„ฐ๋กœ ์ตœ์ ์˜ ๊ทธ๋ฆฌ๋”” ํ•ด๋ฅผ ๊ตฌํ•˜๋Š” ์ด์œ ๋Š” ๋ฐฑํŒฉ ์•ˆ์— ํ…”๋ ˆ๋น„์ „ ๋ฐ˜ ๊ฐœ๋ฅผ ๋„ฃ์„ ์ˆ˜ ์—†๊ณ , ์•„์˜ˆ ์•„์ดํ…œ์„ ๋„ฃ๊ฑฐ๋‚˜ ๋„ฃ์„ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๋กœ๋งŒ ๋‚˜๋‰œ๋‹ค. 

 

์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋กœ์ง์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.


1. ๋ฐฑํŒฉ ์šฉ์ ์ด W์ด๊ณ , ์•„์ดํ…œ์ด ๊ฐ๊ฐ ๊ฐ’์–ด์น˜๊ฐ€ V์ด๊ณ  ๋ฌด๊ฒŒ๊ฐ€ w์ผ ๊ฒฝ์šฐ, v/w ๋น„์œจ(๋ฌด๊ฒŒ ๋Œ€๋น„ ๊ฐ€์น˜, ๊ฐ€์„ฑ๋น„)๋กœ ์•„์ดํ…œ๋“ค์„ ๋‚ด๋ฆผ์ฐจ์ˆœ ์ˆœ์„œ๋Œ€๋กœ ์ •๋ ฌํ•˜์ž.

2. ๊ฐ ์•„์ดํ…œ์„ ๋‹ค์‹œ ์ด ๋น„์œจ๋กœ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜์ž.

3. ๊ฐ€์žฅ ๋น„์œจ์ด ๋†’์€ ์•„์ดํ…œ๋ถ€ํ„ฐ ๋ฐฑํŒฉ์— ๋„ฃ๊ณ , ์™„์ „ํžˆ ๋„ฃ์„ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” ๊ฐ€๋ฐฉ์ด ๊ฐ€๋“ ์ฐฌ ๊ฒƒ์ด๋‹ค.

์ฝ”๋“œ๋กœ ์˜ฎ๊ธฐ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

function ksack(values, weights, capacity) { 
	let load = 0;
    let i = 0;
    let w = 0;
    while (load < capacity && i < 4) {
    	if (weights[i] <= (capacity-load)) {
        	w += values[i];
            load += weights[i];
        } else {
        	let r = (capacity-load)/weights[i]; w += r * values[i];
            load += weights[i];
    	} 
        ++i;
    }
    return w; 
}
    
let items = ["A", "B", "C", "D"];
let values = [50, 140, 60, 60];
let weights = [5, 20, 10, 12];
let capacity = 30;
print(ksack(values, weights, capacity)); // 220

๐Ÿ€ ๋งˆ์น˜๋ฉด์„œ

์˜ค๋Š˜์€ ์‹ฌํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ธ dp์™€ ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•ด ์‚ดํŽด๋ดค๋‹ค.
์™„๋…!๐Ÿฅณ 

 

๐Ÿ“š Reference

- Data Structures and Algorithms Using Javaโ€ Script by Michael McMillian (O’Reilly). Copyright 2014 Michael McMillan, 978-1-449-36493-9