DFS를 사용한 브루트포스
public static long strToLong(String song) {
long sum = 0;
for (int i = 0; i < m; i++) {
char key = song.charAt(i);
if (key == 'Y') {
sum += 1L << i;
}
}
return sum;
}
/**
*
* @param guitarList: 기타 목록
* @param idx: 선택할 기타의 인덱스
* @param playedSong: 지금까지 선택한 기타들로 연주 가능한 노래 bit
* @param guitarCnt: 선택한 기타 수
*/
public static void func(ArrayList<Guitar> guitarList, int idx, long playedSong, int guitarCnt) {
int played = Long.bitCount(playedSong); // 1의 개수를 카운트 -> 지금까지 연주 가능한 노래 수
if (played == maxSong && minGuitar > guitarCnt) { // 연주 가능한 노래 수가 최대와 같고, 선택한 기타 수는 더 적을 경우
minGuitar = guitarCnt;
}
if (played > maxSong) { // 연주 가능한 노래 수가 최대보다 클 경우
maxSong = played;
minGuitar = guitarCnt;
}
if (idx == n || played == m) { // 마지막 기타까지 탐색 완료했거나, 모든 노래를 연주 가능하다면 종료
return;
}
// 현재 기타를 선택할 경우
func(guitarList, idx + 1, playedSong | guitarList.get(idx).playableSongs, guitarCnt + 1);
// 현재 기타를 선택하지 않고 건너뛰는 경우
func(guitarList, idx + 1, playedSong, guitarCnt);
}
package BOJ;
import java.io.*;
import java.util.*;
public class sol1497 {
static int n, m;
static int minGuitar = Integer.MAX_VALUE;
static int maxSong = Integer.MIN_VALUE;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
ArrayList<Guitar> guitarList = new ArrayList<>();
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
guitarList.add(new Guitar(st.nextToken(), strToLong(st.nextToken())));
}
func(guitarList, 0, 0, 0);
System.out.println(maxSong == 0 ? -1 : minGuitar);
}
/**
*
* @param guitarList: 기타 목록
* @param idx: 선택할 기타의 인덱스
* @param playedSong: 지금까지 선택한 기타들로 연주 가능한 노래 bit
* @param guitarCnt: 선택한 기타 수
*/
public static void func(ArrayList<Guitar> guitarList, int idx, long playedSong, int guitarCnt) {
int played = Long.bitCount(playedSong); // 1의 개수를 카운트 -> 지금까지 연주 가능한 노래 수
if (played == maxSong && minGuitar > guitarCnt) { // 연주 가능한 노래 수가 최대와 같고, 선택한 기타 수는 더 적을 경우
minGuitar = guitarCnt;
}
if (played > maxSong) { // 연주 가능한 노래 수가 최대보다 클 경우
maxSong = played;
minGuitar = guitarCnt;
}
if (idx == n || played == m) { // 마지막 기타까지 탐색 완료했거나, 모든 노래를 연주 가능하다면 종료
return;
}
// 현재 기타를 선택할 경우
func(guitarList, idx + 1, playedSong | guitarList.get(idx).playableSongs, guitarCnt + 1);
// 현재 기타를 선택하지 않고 건너뛰는 경우
func(guitarList, idx + 1, playedSong, guitarCnt);
}
public static long strToLong(String song) {
long sum = 0;
for (int i = 0; i < m; i++) {
char key = song.charAt(i);
if (key == 'Y') {
sum += 1L << i;
}
}
return sum;
}
public static class Guitar {
String name;
long playableSongs;
Guitar(String name, long playableSongs) {
this.name = name;
this.playableSongs = playableSongs;
}
}
}
비트마스킹을 이용한 브루트포스
n개의 기타가 있으므로 가능한 조합은 가지
이를 비트마스크로 나타내면, 1 << n
1부터 (1 << n) - 1까지 모든 조합을 탐색하며 노래를 최대한 많이 연주하였을 때, 최소의 기타 개수를 구한다.
package BOJ;
import java.io.*;
import java.util.*;
public class sol1497_2 {
static int n, m;
static int minGuitar = Integer.MAX_VALUE;
static int maxSong = Integer.MIN_VALUE;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
ArrayList<Guitar> guitarList = new ArrayList<>();
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
guitarList.add(new Guitar(st.nextToken(), strToLong(st.nextToken())));
}
int mask = 1 << n;
for (int i = 1; i < mask; i++) { // 각 조합을 전부 탐색
int guitarCnt = Integer.bitCount(i);
int songCnt = 0;
long playedSongs = 0;
for (int j = 0; j < n; j++) { // 사용된 기타로 연주 가능한 곡 탐색
if ((i & 1 << j) != 0) {
Guitar guitar = guitarList.get(j);
playedSongs |= guitar.playableSongs;
}
songCnt = Long.bitCount(playedSongs);
}
if (songCnt == maxSong && guitarCnt < minGuitar) {
minGuitar = guitarCnt;
}
if (songCnt > maxSong) {
minGuitar = guitarCnt;
maxSong = songCnt;
}
}
System.out.println(maxSong == 0 ? -1 : minGuitar);
}
public static long strToLong(String song) {
long sum = 0;
for (int i = 0; i < m; i++) {
char key = song.charAt(i);
if (key == 'Y') {
sum += 1L << i;
}
}
return sum;
}
public static class Guitar {
String name;
long playableSongs;
Guitar(String name, long playableSongs) {
this.name = name;
this.playableSongs = playableSongs;
}
}
}