Algorithm/λ¬Έμ œν’€μ΄

[λ°±μ€€] 2293번 - 동전 1 (C++)

moaoh 2023. 8. 26. 00:45

 

2293번: 동전 1

첫째 쀄에 n, kκ°€ μ£Όμ–΄μ§„λ‹€. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) λ‹€μŒ n개의 μ€„μ—λŠ” 각각의 λ™μ „μ˜ κ°€μΉ˜κ°€ μ£Όμ–΄μ§„λ‹€. λ™μ „μ˜ κ°€μΉ˜λŠ” 100,000보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€.

www.acmicpc.net

문제

nκ°€μ§€ μ’…λ₯˜μ˜ 동전이 μžˆλ‹€. 각각의 동전이 λ‚˜νƒ€λ‚΄λŠ” κ°€μΉ˜λŠ” λ‹€λ₯΄λ‹€. 이 동전을 μ λ‹Ήνžˆ μ‚¬μš©ν•΄μ„œ, κ·Έ κ°€μΉ˜μ˜ 합이 k원이 λ˜λ„λ‘ ν•˜κ³  μ‹Άλ‹€. κ·Έ 경우의 수λ₯Ό κ΅¬ν•˜μ‹œμ˜€. 각각의 동전은 λͺ‡ κ°œλΌλ„ μ‚¬μš©ν•  수 μžˆλ‹€.

μ‚¬μš©ν•œ λ™μ „μ˜ ꡬ성이 같은데, μˆœμ„œλ§Œ λ‹€λ₯Έ 것은 같은 κ²½μš°μ΄λ‹€.

 

 

 

μž…λ ₯

첫째 쀄에 n, kκ°€ μ£Όμ–΄μ§„λ‹€. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) λ‹€μŒ n개의 μ€„μ—λŠ” 각각의 λ™μ „μ˜ κ°€μΉ˜κ°€ μ£Όμ–΄μ§„λ‹€. λ™μ „μ˜ κ°€μΉ˜λŠ” 100,000보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€.

 

 

 

좜λ ₯

첫째 쀄에 경우의 수λ₯Ό 좜λ ₯ν•œλ‹€. 경우의 μˆ˜λŠ” 231보닀 μž‘λ‹€.

 

풀이과정

ν•΄λ‹Ή λ¬Έμ œλŠ” "n개의 μ„œλ‘œλ‹€λ₯Έ 동전이 μ£Όμ–΄μ§ˆλ•Œ kλΌλŠ” 동전을 λ§Œλ“€ 수 μžˆλŠ” 경우의 μˆ˜λŠ” λͺ‡κ°€μ§€μΈκ°€?" λΌλŠ” λ¬Έμ œμ˜€μ—ˆλ‹€.

λ„ˆλ¬΄ λͺ»κ·Έλ Έλ‹€..

λ¬Έμ œμ— μ ‘κ·Όν•˜λŠ” 과정이 생각보닀 κΉŒλ‹€λ‘œμ› λ˜ κ±° κ°™λ‹€.

정리λ₯Ό ν•΄λ³΄μžλ©΄ 이 문제 μ—­μ‹œ dpμ΄λ‹€λ³΄λ‹ˆ μ΄μ „μ˜ 값을 μ΄μš©ν•΄μ„œ ν˜„μž¬μ˜ 값을 κ΅¬ν•˜λŠ” 방식은 λ§žμ•˜μ—ˆλ‹€.

λ™μ „μ˜ μ’…λ₯˜ n을 각자 λ³΄λŠ” λ°©μ‹μœΌλ‘œ 풀이가 이루어진닀.

 

μ˜ˆμ‹œλ₯Ό λ“€μ–΄

2 10
1
2

ν˜•μ‹μœΌλ‘œ μ˜ˆμ‹œκ°€ λ“€μ–΄μ™”λ‹€κ³  가정을 해보고 1 ~ 6κΉŒμ§€ ꡬ해보면

1 : 1 						: 1
2 : 1 1 | 2 					: 2
3 : 1 1 1 | 2 1 				: 2
4 : 1 1 1 1 | 2 1 1 | 2 2			: 3
5 : 1 1 1 1 1 | 2 1 1 1 | 2 2 1			: 3
6 : 1 1 1 1 1 1 | 2 1 1 1 1 | 2 2 1 1 | 2 2 2	: 4
.
.
.

ν˜•μ‹μœΌλ‘œ μ „κ°œκ°€ λ˜λŠ” 방식이고, μœ„μ™€ 같은 λͺ¨μŠ΅μ—μ„œ 2의 λ°°μˆ˜λ§ˆλ‹€ κ°€μ§“μˆ˜κ°€ 1μ”© μ¦κ°€ν•˜λŠ” λͺ¨μŠ΅μ„ 확인할 수 μžˆλ‹€.

μœ„μ˜ 상황을 톡해 ν˜„μž¬μ‚¬μš©ν•˜λŠ” λ™μ „μ˜ 크기의 λ°°μˆ˜λ§ˆλ‹€ 값이 μƒˆλ‘­κ²Œ 갱신이 λœλ‹€λŠ” 것을 확인할 수 μžˆμ–΄μ„œ

2차원 λ°°μ—΄ ν˜•μ‹μœΌλ‘œ 점화식을 μ „κ°œν•΄λ³΄λ©΄

dp[y][x] = dp[y - 1][x] + dp[y][x - ν˜„μž¬ μ‚¬μš©ν•˜λŠ” λ™μ „μ˜ 크기] λΌλŠ” 것을 λ³Ό 수 있고,

λ¬Έμ œμ—μ„œ μš”κ΅¬ν•˜λŠ” λ©”λͺ¨λ¦¬μ˜ 크기가 4MB밖에 μ•ˆλ˜μ–΄μ„œ 1차원 λ°°μ—΄ ν˜•μ‹μœΌλ‘œ μ€„μ—¬λ³΄μžλ©΄
μ΄μ „μ˜ κ΅¬ν•œ [y - 1]의 값을 λ°”νƒ•μœΌλ‘œ ν˜„μž¬μ˜ [y]값을 κ΅¬μƒν•˜λŠ” λ°©μ‹μ΄λ‹ˆ

dp[n] = dp[n](μ΄μ „μ˜ κ΅¬ν•œ κ°’) + dp[n - ν˜„μž¬ μ‚¬μš©ν•˜λŠ” λ™μ „μ˜ 크기] ν˜•μ‹μœΌλ‘œ 점화식을 μ„ΈμšΈ 수 μžˆλ‹€λŠ” 것을 확인 ν•  수 μžˆμ—ˆλ‹€.

code

#include <iostream>

int		coin[101];
int		dp[10001];

int main(void)
{
	int n, k, temp;

	std::cin >> n >> k;
	for (int i = 0; i < n; i++) {
		std::cin >> coin[i];
	}
	for (int i = 0; i < n; i++) {
		for (int j = 1; j <= k; j++) {
			temp = dp[j];
			if (coin[i] == j) dp[j]++;
			if (1 <= j - coin[i])
				dp[j] = temp + dp[j - coin[i]];
		}
	}
	std::cout << dp[k] << "\n";

	return (0);
}

 

ν›„κΈ°

dpμ΄κΈ΄ν•˜μ§€λ§Œ 이 λ¬Έμ œλŠ” ν‰μ†Œμ— ν’€λ˜ dpμ™€λŠ” 살짝 λ‹€λ₯΄κ²Œ μ‘μš©κΉŒμ§€κ°€ ν¬ν•¨λœ λŠλ‚Œμ΄μ—ˆλ‹€.

μ ‘κ·Όν•˜κΈ°κΉŒμ§€ λ§Žμ€ λ…Έλ ₯이 ν•„μš”ν–ˆλ˜ λ¬Έμ œκ°™λ‹€.