작성
·
185
·
수정됨
0
// Online C++ compiler to run C++ program online
#include <bits/stdc++.h>
using namespace std;
//// 다이어트
int N,mp,mf,ms,mv;
int resultSet;
vector<int> resultSetVector;
typedef struct food{
int v[5];
}food;
food* input(){
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
cin>>N>>mp>>mf>>ms>>mv;
food* fList = (food*) malloc(sizeof(food) * N);
for(int i=0; i<N; i++){
for(int j=0; j<5; j++){
cin >> fList[i].v[j];
}
}
return fList;
}
void printBitSet(int resultSet, int N){
for(int i=0;i<N; i++){
if( resultSet & (1<<i) ) {
cout << i + 1 << " ";
}
}
}
//// logic
// 1. 모든 조합을 구한다.
// 2. 해당 조합 중에 최소 영양소 기준을 만족하는 조합을 찾는다.
// 3. 해당 조합 중 최소 비용 조합을 찾는다.
void solve(){
food* fList = input();
int result = INT_MAX;
for(int i=0; i<(1<<N); i++){//O(N^2)
//1.
int sum[5] = {0};
for(int j=0;j<N;j++){
if(i&(1<<j)){
sum[0] += fList[j].v[0];//pi
sum[1] += fList[j].v[1];//fi
sum[2] += fList[j].v[2];//si
sum[3] += fList[j].v[3];//vi
sum[4] += fList[j].v[4];//ci
}
}
//2.mp,mf,ms,mv
if(sum[0] >= mp && sum[1] >= mf && sum[2] >= ms && sum[3] >= mv){
//3.
if(result >= sum[4]){
result = sum[4];
resultSet = i;//최소 비용 조합
}
}
}
if(result == INT_MAX) cout << -1 << '\n';
else{
cout << result << "\n";
printBitSet(resultSet, N);
}
}
int main(){
solve();
}
void printBitSet(int resultSet, int N){
for(int i=0;i<N; i++){
if( resultSet & (1<<i) ) {
cout << i + 1 << " ";
}
}
////.....
//2.mp,mf,ms,mv
if(sum[0] >= mp && sum[1] >= mf && sum[2] >= ms && sum[3] >= mv){
//3.
if(result >= sum[4]){
result = sum[4];
resultSet = i;//최소 비용 조합
}
}
////.....
if(result == INT_MAX) cout << -1 << '\n';
else{
cout << result << "\n";
printBitSet(resultSet, N);//최소 비용 조합 출력
}}
안녕하세요 큰돌 님. 비트마스킹 문제 질문이 있어 여쭤봅니다. 어떤 반례가 있을지 궁금합니다.
vector에 넣어주는 방식이 아니라, i 비트값을 업데이트 해서 프린트 해주는 방식으로 구현 했습니다.
위 방식만 다르기 때문에 여기서 문제가 있을 거라 추측됩니다.
12퍼센트 쯤에서 테케
통과를 못 하더라구요ㅠ
도와주시면 정말 감사드리겠습니다.
답변 2
0
저 코드 중심으로 본다고 치면요.
아마 순차적으로 1 2 3 4 ...이렇게 순회 되기 때문에 사전순정렬을 굳이 vector에다가 담아서 할 필요없다.
라고 생각해서 그렇게 짜신 것 같은데요.
이러한 반례가 있습니다.
-정수 5 = 0101 (식재료 1 4)
-정수 11 = 1011 (식재료 1 2 8)
정수 기준 오름차순 정렬시 5가 11보다 앞쪽에 오게 되는데,
문제에서 요구하는 사전순으로 볼때는 1,2,8 의 경우가 더 앞쪽에 오게 됩니다.
또 질문 있으시면 언제든지 질문 부탁드립니다.
좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)
감사합니다.
강사 큰돌 올림.
0
음.. 공유소스보기 누르면 맞았습니다. 하는 코드가 뜨는데 혹시 잘못 올려주신게 아닐까요?
// Online C++ compiler to run C++ program online
#include <bits/stdc++.h>
using namespace std;
//// 다이어트
int N,mp,mf,ms,mv;
int resultSet;
vector<int> res
이 코드 중심으로 봐드리면 될까요?
안녕하세요 ㅎㅎ 제 답변으로 해결되신거죠..? ㅎㅎ
이번 문제는 반례를 생각하기가 좀 어렵긴했는데요.
제 강의 중 이부분 참고하시면 될 것 같습니다.
다만...
많이 연습해보는 것이 "정해"긴합니다.
감사합니다.
감사합니다! 해당 링크는 문제 해설 pdf에 있는 해답입니다 ㅎㅎ. 혹시 문제 풀고 반례를 생각해볼 때 어떤 식으로 접근하시는지 여쭤봐도 될까요?
물론 많이 연습해보는 게 좋겠지만 혹시라도 팁이 있으신지 여쭤보고 싶습니다!