인프런 커뮤니티 질문&답변

euijae.lee0714님의 프로필 이미지
euijae.lee0714

작성한 질문수

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

4-A

4-a

작성

·

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퍼센트 쯤에서 테케

    통과를 못 하더라구요ㅠ

     

    도와주시면 정말 감사드리겠습니다.

     

 공유 소스 보기 (acmicpc.net)

 

답변 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에 있는 해답입니다 ㅎㅎ. 혹시 문제 풀고 반례를 생각해볼 때 어떤 식으로 접근하시는지 여쭤봐도 될까요?

물론 많이 연습해보는 게 좋겠지만 혹시라도 팁이 있으신지 여쭤보고 싶습니다!

 

 

큰돌님의 프로필 이미지
큰돌
지식공유자

안녕하세요 ㅎㅎ 제 답변으로 해결되신거죠..? ㅎㅎ

이번 문제는 반례를 생각하기가 좀 어렵긴했는데요.

https://www.inflearn.com/course/lecture?courseSlug=10%EC%A3%BC%EC%99%84%EC%84%B1-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%81%B0%EB%8F%8C&unitId=144195&tab=curriculum

제 강의 중 이부분 참고하시면 될 것 같습니다.

 

다만...

많이 연습해보는 것이 "정해"긴합니다.


감사합니다.

넵 감사합니다 큰돌님!

euijae.lee0714님의 프로필 이미지
euijae.lee0714

작성한 질문수

질문하기