let's get IT with DAVINA πŸ’»

[μ•Œκ³ λ¦¬μ¦˜ μœ ν˜•] Greedy Algorithm λ³Έλ¬Έ

DEV_IN/Algorithm

[μ•Œκ³ λ¦¬μ¦˜ μœ ν˜•] Greedy Algorithm

λ‹€λΉˆμΉ˜μ½”λ“œπŸ’Ž 2023. 3. 7. 01:25

Greedy Algorithm (νƒμš• μ•Œκ³ λ¦¬μ¦˜)

μ„ νƒμ˜ μˆœκ°„λ§ˆλ‹€ λ‹Ήμž₯ λˆˆμ•žμ— λ³΄μ΄λŠ” 졜적의 μƒν™©λ§Œμ„ μ«“μ•„ μ΅œμ’…μ μΈ 해닡에 λ„λ‹¬ν•˜λŠ” 방법

 

Greedy Algorithm 문제 ν•΄κ²° 단계 πŸ”½

  1. 선택 절차(Selection Procedure): ν˜„μž¬ μƒνƒœμ—μ„œμ˜ 졜적의 해닡을 μ„ νƒν•©λ‹ˆλ‹€.
  2. μ μ ˆμ„± 검사(Feasibility Check): μ„ νƒλœ ν•΄κ°€ 문제의 쑰건을 λ§Œμ‘±ν•˜λŠ”μ§€ κ²€μ‚¬ν•©λ‹ˆλ‹€.
  3. ν•΄λ‹΅ 검사(Solution Check): μ›λž˜μ˜ λ¬Έμ œκ°€ ν•΄κ²°λ˜μ—ˆλŠ”μ§€ κ²€μ‚¬ν•˜κ³ , ν•΄κ²°λ˜μ§€ μ•Šμ•˜λ‹€λ©΄ 선택 절차둜 λŒμ•„κ°€ μœ„μ˜ 과정을 λ°˜λ³΅ν•©λ‹ˆλ‹€.
- νƒμš•μ  선택 속성(Greedy Choice Property) : μ•žμ˜ 선택이 μ΄ν›„μ˜ 선택에 영ν–₯을 주지 μ•ŠμŠ΅λ‹ˆλ‹€.
- 졜적 λΆ€λΆ„ ꡬ쑰(Optimal Substructure) : λ¬Έμ œμ— λŒ€ν•œ μ΅œμ’… ν•΄κ²° 방법은 λΆ€λΆ„ λ¬Έμ œμ— λŒ€ν•œ 졜적 문제 ν•΄κ²° λ°©λ²•μœΌλ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€.

→ 이 두가지 쑰건을 λ§Œμ‘±ν•˜λŠ” "νŠΉμ •ν•œ 상황"이 μ•„λ‹ˆλ©΄ 졜적의 ν•΄λ₯Ό 보μž₯ν•  수 μ—†λ‹€
→ 즉, νƒμš• μ•Œκ³ λ¦¬μ¦˜μ€ 항상 졜적의 κ²°κ³Όλ₯Ό λ„μΆœν•˜λŠ” 것은 μ•„λ‹ˆμ§€λ§Œ, μ–΄λŠ 정도 μ΅œμ μ— κ·Όμ‚¬ν•œ 값을 λΉ λ₯΄κ²Œ λ„μΆœν•  수 μžˆλŠ” μž₯점이 μžˆμŠ΅λ‹ˆλ‹€. 이 μž₯점으둜 인해 νƒμš• μ•Œκ³ λ¦¬μ¦˜μ€ 근사 μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

예제 (κ±°μŠ€λ¦„λˆ)

β“λ¬Έμ œ 상황

νƒ€λ‘œλŠ” 자주 JOI μž‘ν™”μ ‘μ—μ„œ 물건을 μ‚°λ‹€. JOI μž‘ν™”μ μ—λŠ” μž”λˆμœΌλ‘œ 500μ—”, 100μ—”, 50μ—”, 10μ—”, 5μ—”, 1엔이 μΆ©λΆ„νžˆ 있고, μ–Έμ œλ‚˜ κ±°μŠ€λ¦„λˆ κ°œμˆ˜κ°€ κ°€μž₯ 적게 μž”λˆμ„ μ€€λ‹€. νƒ€λ‘œκ°€ JOI μž‘ν™”μ μ—μ„œ 물건을 사고 μΉ΄μš΄ν„°μ—μ„œ 1000μ—” 지폐λ₯Ό ν•œ μž₯ λƒˆμ„ λ•Œ, 받을 μž”λˆμ— ν¬ν•¨λœ μž”λˆμ˜ 개수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.
380엔을 νƒ€λ‘œκ°€ μ§€λΆˆμ„ ν•΄μ•Ό ν•œλ‹€λ©΄ νƒ€λ‘œκ°€ λ°›μ•„μ•Ό ν•  κ±°μŠ€λ¦„λˆμ€ 620μ—”μž…λ‹ˆλ‹€. κ·Έλ ‡λ‹€λ©΄ 500μ—” 1개, 100μ—” 1개, 10μ—” 2개둜 총 4개의 동전을 거슬러 λ°›λŠ” 것이 κ°€μž₯ 적게 μž”λˆμ„ 거슬러 λ°›λŠ” 방법일 κ²ƒμž…λ‹ˆλ‹€. κ°€μž₯ 적게 거슬러 λ°›κΈ° μœ„ν•œ λ‘œμ§μ„ μž‘μ„±ν•΄λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.
function keepTheChange(input) {
	
	//1000μ—”μ§œλ¦¬ 지폐λ₯Ό λƒˆλ‹€λŠ” 가정이 있고, μž…λ ₯ κ°’μœΌλ‘œλŠ” μ§€λΆˆν•΄μ•Ό ν•  κΈˆμ•‘μ΄ λ“€μ–΄μ˜΅λ‹ˆλ‹€.
	let change = Number(1000 - input);
	//μΉ΄μš΄νŠΈν•˜κΈ° μœ„ν•΄ λ³€μˆ˜ count에 0을 ν• λ‹Ήν•©λ‹ˆλ‹€. 
	let count = 0;
	
	//μž…λ ₯ 값에 배열이 λ“€μ–΄μ˜€μ§€ μ•ŠμœΌλ―€λ‘œ 직접 큰 μž”λˆ μˆœμ„œλŒ€λ‘œ 배열을 λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.
	const joiCoins = [500, 100, 50, 10, 5, 1];

	//λ§Œλ“  λ°°μ—΄μ˜ 개수만큼만 λŒλ €μ€˜μ•Ό ν•©λ‹ˆλ‹€.
	for(let i = 0; i < joiCoins.length; i++){
		//κ±°μŠ€λ¦„λˆμ΄ 0원이 되면 for문을 멈μΆ₯λ‹ˆλ‹€.
		if(change === 0) break;
		
		//κ±°μŠ€λ¦„λˆκ³Ό μž”λˆμ„ λ‚˜λˆˆ λͺ«μ„ μΉ΄μš΄νŒ…ν•©λ‹ˆλ‹€.(쓰인 μž”λˆμ˜ 개수 μΉ΄μš΄νŒ…)
		count += Math.floor(Number(change/joiCoins[i]));
		//κ±°μŠ€λ¦„λˆμ„ μž”λˆμœΌλ‘œ λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό μž¬ν• λ‹Ήν•©λ‹ˆλ‹€.
		change %= joiCoins[i];

	}
	
	//countλ₯Ό λ¦¬ν„΄ν•©λ‹ˆλ‹€.
	return count;
}
Comments