티스토리 뷰
>문제
상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그램 봉지와 5킬로그램 봉지가 있다.
상근이는 귀찮기 때문에, 최대한 적은 봉지를 들고 가려고 한다. 예를 들어, 18킬로그램 설탕을 배달해야 할 때, 3킬로그램 봉지 6개를 가져가도 되지만, 5킬로그램 3개와 3킬로그램 1개를 배달하면, 더 적은 개수의 봉지를 배달할 수 있다.
상근이가 설탕을 정확하게 N킬로그램 배달해야 할 때, 봉지 몇 개를 가져가면 되는지 그 수를 구하는 프로그램을 작성하시오.
> 핵심
나머지 연산
동적 계획법(다이나믹 프로그래밍)
>풀이과정
N kg의 설탕에서 3kg씩 빼다가, 5, 10, 15 등 5의 배수와 만나면 5kg씩 빼서 0kg을 맞춘다.
5의 배수와 만나지 못해 3kg씩 빼다가 N이 0보다 작아져 반복문을 탈출하면 -1을 출력한다.
별로 안어렵다!
===============
3월 10일 추가
이 문제는 나머지 연산으로 풀 수도 있지만 다이나믹 프로그래밍으로도 풀 수 있다고 한다.
다이나믹 프로그래밍을 접한지 얼마 안돼서 연습차원에서 다시 풀었다.
아직 개념이 잘 안잡혀서 헷갈리는데 관련 문제를 많이 풀어봐야겠다
>코드
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int N, cnt = 0;
scanf("%d", &N);
while (N > 0)
{
if (N % 5 == 0) // 설탕이 5로 나뉘어지면
{
cnt += 1;
N -= 5;
}
else
{
cnt += 1;
N -= 3;
}
}
if (N != 0 || cnt == 0)
printf("-1\n");
else
printf("%d\n", cnt);
}
다이나믹 프로그래밍 버전
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int dp[10001];
int dynamic(int n)
{
if (n < 3 || n == 4) return 0;
if (n == 3) return 1;
if (n == 5) return 1;
// 메모이제이션!
if (dp[n] != 0) return dp[n];
int cnt_3, cnt_5;
for (int i = 6; i <= n; i++)
{
cnt_3 = dynamic(n - 3);
cnt_5 = dynamic(n - 5);
// 3kg 봉지를 더할 수 있는 경우
if (cnt_3 == 0 && cnt_5 != 0)
dp[n] = cnt_5 + 1;
// 5kg 봉지를 더할 수 있는 경우
else if (cnt_5 == 0 && cnt_3 != 0)
dp[n] = cnt_3 + 1;
// 둘 다 더할 수 있는 경우. 둘중 작은 값을 찾아 더한다.
else if (cnt_3 != 0 && cnt_5 != 0)
cnt_3 < cnt_5 ? (dp[n] = cnt_3 + 1) : (dp[n] = cnt_5 + 1);
}
return dp[n];
}
int main()
{
int n, m;
scanf("%d", &n);
m = dynamic(n);
// m == 0인 경우 >> 딱 떨어지게 나눠담을 수 없는경우
if (m == 0)
printf("-1\n");
else
printf("%d\n", m);
return 0;
}
'알고리즘 > 기타' 카테고리의 다른 글
[C] 백준 | 1018번 코드 - 체스판 다시 칠하기 (0) | 2021.02.22 |
---|---|
[C] 백준 | 2869번 코드 - *달팽이는 올라가고 싶다 (0) | 2021.02.21 |
[C] 백준 | 15829번 코드 - Hashing (0) | 2021.02.21 |
[C] 백준 | 2292번 코드 - *벌집 (0) | 2021.02.21 |
[C] 백준 | 2775번 코드 - *부녀회장이 될테야 (0) | 2021.02.21 |
댓글