https://www.acmicpc.net/problem/19942
* 개선할점
- 비트마스킹 패턴 암기필요
- subset 은 정수 1 부터 2^n -1 (255)까지
- 이를 비트연산 하면서 비트가 켜져있으면, 해당 원소를 선택한다.
- if문아래에 로직을 넣는다.
- 이때, 선택된원소들은 1-idx이므로 i+1 해준값을 결과에 저장한다.
- 정답이 여러개인 경우
- map<int, vector<vector<int>>>에 가격별 정답후보들을 담는다. // m[300] : {1,2,3 / 4,5,6}
- 이를 정렬후 m[ret][0]을 꺼내면 원하는 idx들이 출력된다.
* 전체코드
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,mp,mf,ms,mv;
int arr[16][6];
int ret=987654321; //최소비용구하기, 초기화=최대로
map<int, vector<vector<int>>> m; // 비용별 정답들
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin>>n>>mp>>mf>>ms>>mv;
for(int i=0;i<n;++i) {
for(int j=0;j<5;++j) {
cin>>arr[i][j];
}
}
//전체 부분집합에 대해( 1 ~ 2^n -1 ) ( 0 0 0 0 1 ~ 1 1 1 1 1 )
for(int subset = 1; subset < (1 << n); ++subset) {
// for(int subset = 8+4+2; subset <= 8+4+2; ++subset) {
int a=0,b=0,c=0,d=0, e=0;
vector<int> tmp; //정답 index들 후보
//한칸씩 보면서 비트가 켜져있는지 검사
//비트가 켜져있는경우 해당 재료를 선택
for(int i=0; i< n;++i) {
if(subset & (1<<i)) {
a+=arr[i][0];
b+=arr[i][1];
c+=arr[i][2];
d+=arr[i][3];
e+=arr[i][4];
tmp.push_back(i+1); // 1-idx로 바꾸기
}
}
if(a<mp || b<mf || c<ms || d<mv) continue;
if(ret >= e) { //현재가 더 싼경우
ret=e;
m[ret].push_back(tmp);
}
}
if(ret==987654321) {
cout<<-1;
return 0;
}
cout<<ret<<"\n";
sort(m[ret].begin(),m[ret].end());
for(auto i : m[ret][0]) {
cout<<i<<" ";
}
return 0;
}
'Algorithm > 비트마스킹' 카테고리의 다른 글
[알고리즘] 백준 1062 가르침 // 조합, 비트마스킹, 백트래킹 (0) | 2025.01.11 |
---|---|
[알고리즘] 백준 1987 알파벳 // 비트마스킹, i번째 비트켜짐확인, vis를 숫자1개로 나타내는 힘 (0) | 2025.01.11 |
[알고리즘] 백준 17471 게리멘더링 // 비트마스킹, dfs 구역체크는 노드1곳에서 시작 (0) | 2025.01.08 |
[알고리즘] 백준 1285 동전뒤집기 // 비트마스킹, 상태가 2개면 비트마스킹을 생각 (0) | 2025.01.08 |
리트코드 1비트의 갯수 c++ //비트마스킹, 최하위 1지우는법 (0) | 2024.05.18 |