DP (배낭 문제)

2025. 4. 11. 12:49·알고리즘(코딩테스트)

1. 특징


배낭 문제 유형의 경우, 특정 스텝을 나아가는 도중에 "제약조건" 을 가지고 있어서 해당 조건을 체크해주는 작업이 필요하다.

 

예를 들어,

  • 물건들을 고르는 방법의 수를 구하는데 "최대 무게"가 정해져 있음
  • 동전을 모으는 방법의 수를 구하는데 "최대 금액" 이 정해져 있음
  • 인사를 하면서 얻는 기쁨을 구하는데 "최대 체력"이 정해져 있음 

 

그렇기 때문에, 이중 for문을 사용해야 하는 경우가 많다.

  • step을 밟아 나가는 for문
  • 제약조건을 지켜주는 for문

 

2. 예시


https://www.acmicpc.net/problem/1535

 

이 문제는 가장 스탠다드한 형태의 문제이다.

  • 바깥 for문을 통해 step을 밟아 나가면서
  • 안쪽 for문을 통해서 제약조건을 지켜준다.
더보기
#include <iostream>
using namespace std;

int n;
pair<int, int> board[22];
int dp[22][102]; //현재 i번째 왔을때 남은 체력 j 일때의 기쁨
int answer = 0;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n;
	for (int i = 1; i <= n; ++i)
	{
		cin >> board[i].first; //체력
	}
	for (int i = 1; i <= n; ++i)
	{
		cin >> board[i].second; //기쁨
	}
	
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 100; j >= 0; --j)
		{
			if (j - board[i].first > 0)
			{
				dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - board[i].first] + board[i].second);
			}
			else
			{
				dp[i][j] = dp[i - 1][j];
			}
			answer = max(answer, dp[i][j]);
		}
	}

	cout << answer;
}

 

https://www.acmicpc.net/problem/12865

 

이 문제는 가장 기본적인 배낭문제이다.

  • 위의 문제와 같은 방식으로 풀 수 있다.
더보기
#include <iostream>
using namespace std;

int n, k;
pair<int, int> props[102];
int dp[102][100'002];
int answer = 0;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> k;

	for (int i = 1; i <= n; ++i)
	{
		int w, v;
		cin >> w >> v;

		props[i].first = w;
		props[i].second = v;
	}

	for (int i = 1; i <= n; ++i)
	{
		for (int j = 0; j <= k; ++j)
		{
			//넣을 수 있다면,
			if (j + props[i].first <= k)
				dp[i][j] = max(dp[i - 1][j], dp[i - 1][j + props[i].first] + props[i].second);
			else
				dp[i][j] = dp[i - 1][j];

			answer = max(answer, dp[i][j]);
		}
	}
	cout << answer;
}

 

https://www.acmicpc.net/problem/9084

이 문제는 조금 다른 방식으로 풀이를 했다. 

더보기
#include <iostream>
using namespace std;

int t;
int coins[22];
int dp[10002];

//n개의 동전으로 m 만들기
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> t;

	while (t--)
	{
		int n;
		int m;
		int answer = 0;

		cin >> n;

		fill(coins, coins + 22, 0);
		fill(dp, dp + 10002, 0);

		for (int i = 1; i <= n; ++i)
		{
			cin >> coins[i];
		}
		cin >> m;
		dp[0] = 1;

		for (int i = 1; i <= n; ++i)
		{
			for (int j = coins[i]; j <= m; ++j)
			{
				dp[j] += dp[j - coins[i]];
			}
		}
		cout << dp[m] << "\n";
	}

}

 

https://www.acmicpc.net/problem/2293

위 문제와 거의 유사한 문제

더보기
#include <iostream>
#include <algorithm>
using namespace std;

int n, k;
int value[102];
int dp[100'002];

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n >> k;

	for (int i = 0; i < n; ++i)
	{
		cin >> value[i];
	}
	sort(value, value + n);
	dp[0] = 1;
	for (int i = 0; i < n; ++i)
	{
		for (int j = value[i]; j <= k; ++j)
		{
			dp[j] += dp[j - value[i]];
		}
	}
	cout << dp[k];
}

 

'알고리즘(코딩테스트)' 카테고리의 다른 글

MST  (0) 2025.04.25
LCS  (0) 2025.04.23
백트래킹 2  (0) 2025.04.04
최단 경로 구하기 (다익스트라, 벨만-포드)  (0) 2025.03.25
정렬 및 탐색 알고리즘 정리  (0) 2025.03.21
'알고리즘(코딩테스트)' 카테고리의 다른 글
  • MST
  • LCS
  • 백트래킹 2
  • 최단 경로 구하기 (다익스트라, 벨만-포드)
gbleem
gbleem
gbleem 님의 블로그 입니다.
  • gbleem
    gbleem 님의 블로그
    gbleem
  • 전체
    오늘
    어제
    • 분류 전체보기 (184)
      • Unreal Engine (73)
      • C++ (19)
      • 알고리즘(코딩테스트) (27)
      • TIL (60)
      • CS (4)
      • 툴 (1)
  • 블로그 메뉴

    • 홈
    • 카테고리
  • 링크

    • 과제용 깃허브
    • 깃허브
    • velog
  • 공지사항

  • 인기 글

  • 태그

    매크로 지정자
    상속
    DP
    motion matching
    character animation
    템플릿
    map을 vector로 복사
    blend pose
    BFS
    additive animation
    cin함수
    addonscreendebugmessage
    Vector
    C++
    const
    enhanced input system
    applydamage
    gamestate
    actor 클래스
    싱글턴
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
gbleem
DP (배낭 문제)
상단으로

티스토리툴바