[백준 2961번 C/C++] 도영이가 만든 맛있는 음식

 

https://www.acmicpc.net/problem/2961


 

 

해결전략

 

비트마스킹 Bitmasking

 


 

처음 시도한 코드 - 시간초과

 

#include <iostream>
#include <set>
#include <vector>
using namespace std;
int n;
long long answer = 987654321;
vector<int> sour, bitter;
vector<pair<int, int>> taste;
void DFS(int idx, vector<int>& ch, set<int>& foods)
{
if (idx == n){
long long sour = 1, bitter = 0;
for (auto& iter : foods){
sour *= taste[iter].first;
bitter += taste[iter].second;
}
answer = min(answer, abs(sour - bitter));
return;
}
for (int i = 0; i < n; i++)
{
if (ch[i] == 0)
{
ch[i] = 1;
foods.insert(i);
DFS(idx + 1, ch, foods);
foods.erase(i);
ch[i] = 0;
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n;
taste.resize(n);
for (int i = 0; i < n; i++){
cin >> taste[i].first >> taste[i].second;
}
for (int i = 0; i < n; i++)
{
vector<int> ch(n, 0);
set<int> foods;
DFS(i, ch, foods);
}
cout << answer << "\n";
return 0;
}

 

 

정답코드

 

#include <iostream>
#include <vector>
using namespace std;
int n; // 재료의 개수
long long answer = 987654321; // 최종 답, 충분히 큰 값으로 초기화
vector<pair<int, int>> taste; // 재료의 신맛과 쓴맛을 저장
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n;
taste.resize(n);
for (int i = 0; i < n; i++){
cin >> taste[i].first >> taste[i].second;
}
// 모든 경우의 수((1 << taste.size) -1). ex. n=3라면: 001, 010, 011, 100, 101, 111
// 비트마스크를 이용하여 모든 부분 집합을 탐색
for (int bitmask = 1; bitmask < (1 << taste.size()); bitmask++)
{
long long sour = 1, bitter = 0; // 각 부분 집합의 신맛과 쓴맛을 계산할 변수 초기화
// 비트마스크를 이용하여 현재 부분 집합에 포함된 재료를 탐색
for (int i = 0; i < taste.size(); i++)
{
if (bitmask & (1 << i)){ // 현재 i번째 재료가 부분 집합에 포함되어 있는지 확인
sour *= taste[i].first;
bitter += taste[i].second;
//cout << "-- " << taste[i].first << ", " << taste[i].second << "\n";
}
}
//cout << sour << ", " << bitter << "\n\n";
answer = min(answer, abs(sour - bitter));
}
cout << answer << "\n";
return 0;
}