728x90
https://www.acmicpc.net/problem/1062
메모리: 89,116 KB , 시간: 264 ms
사용 알고리즘: 백트래킹, 브루트포스 알고리즘
728x90
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static int K;
static int[] count;
static ArrayList<ArrayList<Integer>> list;
static boolean[] pick;
static int result;
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
// count[i] := i번째 단어가 몇 개의 글자로 이루어져 있는지 저장(i번째 단어를 읽기 위해 몇 개의 글자를 배워야 하는지)
count = new int[N];
// 글자가 어느 단어에 속해 있는지
list = new ArrayList<>();
for (int i = 0; i < 26; i++) {
list.add(new ArrayList<>());
}
char[] tmp;
Set<Character> set;
for (int i = 0; i < N; i++) {
tmp = br.readLine().toCharArray();
set = new HashSet<>();
for (int j = 0; j < tmp.length; j++) {
set.add(tmp[j]);
}
count[i] = set.size();
for (char c : set) {
list.get(c - 'a').add(i);
}
}
// 모든 단어는 "anta"로 시작되고 "tica"로 끝나기 때문에 [a, n, t, i, c] 5개는 필수로 읽을 수 있어야 한다.
if(K < 5) {
System.out.println(0);
return;
}
// 필수로 필요한 [a, n, t, i, c]는 조합에서 빼줌
for (int i = 0; i < N; i++) {
count[i] -= 5;
}
list.remove('t' - 'a');
list.remove('n' - 'a');
list.remove('i' - 'a');
list.remove('c' - 'a');
list.remove('a' - 'a');
// [a, n, t, i, c]만으로 읽을 수 있는 단어 개수
int base = 0;
for (int i = 0; i < N; i++) {
if(count[i] == 0) base++;
}
// K개 만큼 고른 글자
pick = new boolean[21];
// 읽을 수 있는 단어 개수의 최댓값
result = 0;
// 배울 글자 조합 구하기
combi(0, 0);
// 답 출력
System.out.println(base + result);
}
private static void combi(int n, int no) {
// 배울 K개의 글자를 모두 선택한 경우
if(no == K - 5) {
read();
return;
}
if(n == 21) return;
// n번째 글자를 선택하지 않은 경우
combi(n + 1, no);
// n번째 글자를 선택한 경우
pick[n] = true;
combi(n + 1, no + 1);
pick[n] = false;
}
private static void read() { // 배운 단어 조합으로 몇 개의 단어를 읽을 수 있는지 확인하는 메소드
int[] copy_count = count.clone();
int can_read = 0; // 읽을 수 있는 단어 수
for (int i = 0; i < 21; i++) {
if(pick[i]) { // 배우기로 정한 글자라면
for (int j = 0; j < list.get(i).size(); j++) { // 해당 글자를 포함하고 있는 단어에서 배워야 하는 글자 수를 빼줌
if(--copy_count[list.get(i).get(j)] == 0) { // 해당 단어가 포함하고 있는 글자를 모두 배웠다면
can_read++; // 읽을 수 있는 단어수 + 1
}
}
}
}
result = Math.max(result, can_read);
}
}
728x90
'Problem Solving > BOJ' 카테고리의 다른 글
[백준, BOJ 1092] 배 (java) (1) | 2024.06.12 |
---|---|
[백준, BOJ 2233] 함께 블록 쌓기 (java) (0) | 2024.06.05 |
[백준, BOJ 18427] 함께 블록 쌓기 (java) (0) | 2024.06.01 |
[백준, BOJ 2812] 크게 만들기 (java) (0) | 2024.05.31 |
[백준, BOJ 6209] 제자리 멀리뛰기 (java) (0) | 2024.05.28 |