Algorithm/dp
[맞음] 백준 12865 평범한 배낭 c++ // dp는 경우의수로 해결, ox dp
Mini_96
2023. 11. 26. 02:03
https://www.acmicpc.net/problem/12865
12865번: 평범한 배낭
첫 줄에 물품의 수 N(1 ≤ N ≤ 100)과 준서가 버틸 수 있는 무게 K(1 ≤ K ≤ 100,000)가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 ≤ W ≤ 100,000)와 해당 물건의 가치 V(0 ≤ V ≤ 1,000)
www.acmicpc.net
1. dp는 if(dp[i][j]=~~~)
else dp[i][j]=~~~
형태로 해결하라
2. 전체코드
#include <bits/stdc++.h>
using namespace std;
int n, k,ret;
int d[104][100000+4]; // i번째 물건까지 왔을때 최대가치, 제한무개 j
int weight[100 + 4];
int value[100 + 4];
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n >> k;
for (int i = 1; i <= n; ++i) {
int w, v;
cin >> w >> v;
weight[i] = w;
value[i] = v;
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= k; ++j) {
//i번째 물건을 넣을수 없는경우
if (j < weight[i]) {
d[i][j] = d[i - 1][j];
//기존에 탐색했던 물건들을 이용해서 무게 j를 만든 최대가치와 동일
}
//i번째 물건을 넣을수 있는경우
else {
//기존에 탐색했던 물건들로 무게j를 만드는경우
//기존에 탐색했던 물건들로 무게 j-weight[i]를 만들고, 넣기
//중 가치가큰값
d[i][j] = max(d[i - 1][j], d[i - 1][j - weight[i]] + value[i]);
}
}
}
cout << d[n][k];
return 0;
}
* 2회독(25.3.18.)
- 넣는경우, 안넣는경우 이진트리 dp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,k;
vector<pair<int,int>> v; //무게, 가격
ll dp[104][100000+4]; //idx, 남은무게 : 그때 가치 최대값
ll dfs(int idx, int weight) {
if(weight < 0 ) {
return -987654321;
}
if(idx==n) {
return 0;
}
ll & ret = dp[idx][weight];
if(ret!=-1) {
return ret;
}
ret=0; //리프노드 시작 리턴값
ret=max(ret,dfs(idx+1,weight-v[idx].first)+v[idx].second); //담음
ret=max(ret,dfs(idx+1,weight)); //안담음
return ret;
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
memset(dp,-1,sizeof(dp));
cin>>n>>k;
for(int i=0;i<n;++i) {
int w,vv;
cin>>w>>vv;
v.push_back({w,vv});
}
cout<<dfs(0,k);
}
* 큰돌풀이
- 1개갯수제한은? 우측부터 표 dp