티스토리 뷰

>문제

상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그램 봉지와 5킬로그램 봉지가 있다.

상근이는 귀찮기 때문에, 최대한 적은 봉지를 들고 가려고 한다. 예를 들어, 18킬로그램 설탕을 배달해야 할 때, 3킬로그램 봉지 6개를 가져가도 되지만, 5킬로그램 3개와 3킬로그램 1개를 배달하면, 더 적은 개수의 봉지를 배달할 수 있다.

상근이가 설탕을 정확하게 N킬로그램 배달해야 할 때, 봉지 몇 개를 가져가면 되는지 그 수를 구하는 프로그램을 작성하시오.

www.acmicpc.net/problem/2839

 

2839번: 설탕 배달

상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그

www.acmicpc.net

> 핵심

나머지 연산

동적 계획법(다이나믹 프로그래밍)

>풀이과정

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;
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함