
dp를 이용하는 문제
무게가 k인 배낭을 쪼개서 푸는 문제.. 헷갈린다.
1부터 시작될거임dp를 초기화 하는데, 0행부터 n행까지는 해당 인덱스의 물건, 0열부터 k열까지는 배낭의 무게이다.0행이거나 0열일 경우에는 물건이 없거나, 가방이 없는 경우이므로 0으로 초기화 한다.j이다. j 무게의 가방에 물건을 넣을 건데, 무게가 j보다 크면 가방에 못 넣으니까, j 무게 가방에 그 전 물건 넣었을 때 dp값. 그러니까 dp[i-1][j]값이 들어간다. 여기까지 점화식은 if j<wei dp[i][j] = dp[i-1][j]j 무게의 가방보다 현재 물건의 무게가 작으면 일단 들어가긴 할테니 현재 물건을 넣는 경우와 안 넣는 경우를 비교를 해주어야 한다.j-wei가방에 들어가는 전 물건까지의 dp값 + 현재 물건의 가치j가방에 들어가는 전 물건까지의 dp 값 (현재 물건을 안 넣을 거니까)dp[i][j] = max(dp[i-1][j], dp[i-1][j-wei]+val)이 되겠다.k무게 배낭의 n번째 보석까지 넣은 결과인 dp[n][k]를 출력한다.#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n, k;
cin >> n >> k;
vector<pair<int, int>> object;
for (int i = 0; i < n; i++)
{
int w, v;
cin >> w >> v;
object.push_back({ w,v });
}
object.push_back({ 0,0 });
sort(object.begin(), object.end());
vector<vector<int>> dp(n+1, vector<int>(k+1));
for (int i = 0; i < dp.size(); i++)
{
int wei = object[i].first;
int val = object[i].second;
for (int j = 0; j < dp[i].size(); j++)
{
if (i==0 || j == 0)
{
dp[i][j] = 0;
}
else if (j < wei) // 물건의 무게가 가방 무게보다 무거울 경우
{
dp[i][j] = dp[i - 1][j];
}
else
{
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - wei] + val);
}
//cout << dp[i][j] << " ";
}
//cout << endl;
}
cout << dp[n][k] << endl;
}