문제풀이/백준oj
[백준OJ] 19942번 다이어트
Hyeon-Uk
2021. 9. 6. 22:45
반응형
https://www.acmicpc.net/problem/19942
19942번: 다이어트
식재료 N개 중에서 몇 개를 선택해서 이들의 영양분(단백질, 탄수화물, 지방, 비타민)이 일정 이상이 되어야 한다. 아래 표에 제시된 6가지의 식재료 중에서 몇 개를 선택해서 이들의 영양분의 각
www.acmicpc.net
풀이
음식들의 영양소를 모두 입력받은뒤에, 백트래킹을 이용하여 해당 음식을 선택했을때와 , 선택하지 않았을때의 경우를 모두 고려하여 매 함수 진입마다 최솟값을 갱신해주면된다.
시간복잡도
N개의 음식마다 선택의 길이 2가지 경우이므로, O(215)가 된다.
코드
#include<iostream>
#include<algorithm>
#include<vector>
#define MAX 987654321
using namespace std;
//영양소
typedef struct node{
int num, p, f, s, v, c;
}node;
int n, mp, mf, ms, mv,ret=MAX;
vector<int> ret_v;//최솟값의 음식번호를 저장하는 벡터
vector<int> temp_v;//임시벡터
vector<node> foods;
bool visited[15];
int isOver() {
int sp, sf, ss, sv, sc;
sp = sf = ss = sv = sc = 0;
temp_v.clear();
for (int i = 0; i < n; i++) {
if (visited[i]) {
sp += foods[i].p;
sf += foods[i].f;
ss += foods[i].s;
sv += foods[i].v;
sc += foods[i].c;
temp_v.push_back(foods[i].num);
}
}
if (sp >= mp && sf >= mf && ss >= ms && sv >= mv) {
return sc;
}
else {
return -1;
}
}
void dfs(int ind) {
int sum=isOver();
if (sum!=-1&&ret>sum) {
ret = min(ret, sum);
ret_v = temp_v;
}
if (ind == n) {
return;
}
visited[ind] = true;
dfs(ind + 1);
visited[ind] = false;
dfs(ind + 1);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n;
cin >> mp >> mf >> ms >> mv;
for (int i = 0; i < n; i++) {
int p, f, s, v, c;
cin >> p >> f >> s >> v >> c;
foods.push_back({ i + 1,p,f,s,v,c });
}
dfs(0);
if (ret == MAX) {
cout << -1;
}
else {
cout << ret << "\n";
for (int i = 0; i < ret_v.size(); i++) {
cout << ret_v[i] << " ";
}
}
return 0;
}
반응형