백준 - 패션왕 신해빈
구해야 하는 것
- 해빈이가 옷을 하나라도 입은 상태로 며칠 동안 밖에 돌아다닐 수 있는지 구하라
주어진 자료
- 테스트 케이스 <= 100
- 0 <= 해빈이가 가진 의상 수 n <= 30
- 1 <= 모든 문자열 길이 <= 20
- 중복된 의상 이름은 주어지지 않는다.
조건
- 같은 종류의 의상은 하나만 입을 수 있다.
- 한 조합은 두번 다시 입지 않는다.
계획
- 테스트 케이스를 입력받는다.
- n을 입력받는다.
- 의상 종류를 key로, 개수를 value로 갖는 맵을 만든다.
- 만약 맵이 아래와 같이 만들어졌다면,
{ "headgear":2, "eyewear":1 }
모든 경우의 수는 (2C1 + headgear를 모두 선택하지 않는 경우) * (1C1 + eyewear를 모두 선택하지 않는 경우) - (아무것도 입지 않는 경우)
즉, (2C1 + 1) * (1C1 + 1) - 1
실행
public class Main {
HashMap<String, Integer> map;
// 의상을 입을 수 있는 모든 경우의 수 세기
public int countAllCases() {
int cnt = 1;
for(int val : map.values()) {
cnt *= (val + 1); // val = 옷을 각각 하나씩 선택하는 경우의 수, 1 = 한 종류를 전부 선택하지 않는 경우의 수
}
cnt -= 1; // 아무 종류도 선택하지 않는 경우 빼줌
return cnt;
}
public void solution() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int testCase = Integer.parseInt(br.readLine()); // 테스트 케이스 입력
for(int i = 0; i < testCase; i++) {
map = new HashMap<>();
int n = Integer.parseInt(br.readLine()); // n 입력
for(int j = 0; j < n; j++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
String name = st.nextToken(); // (의상 이름은 필요 없음)
String key = st.nextToken();
// 맵에 특정 종류에 대한 옷 개수를 넣어줌
if(map.get(key) == null) {
map.put(key, 1);
} else {
map.put(key, map.get(key) + 1);
}
}
int answer = countAllCases(); // 모든 경우의 수 세기
System.out.println(answer);
}
}
public static void main(String[] args) throws IOException {
new Main().solution();
}
}
반성
- 모든 경우의 수를 세는 공식을 구하는 것이 관건인 문제였다.
처음에는 아래와 같이 접근했었다.- 옷 종류 중 1개를 선택하는 경우
headgear 선택 → headgear의 value에서 1개를 선택하는 경우(2C1)
eyewear 선택 → eyewear의 value에서 1개를 선택하는 경우(1C1) - 옷 종류 중 2개를 선택하는 경우
headgear, eyewear 선택 → headgear의 value에서 1개를 선택하는 경우 * eyewear의 value에서 1개를 선택하는 경우(2C1 * 1C1)
→ 2C1 + 1C1 + (2C1 * 1C1) = 2 + 1 + 2 = 5
이걸 단순하게 바꾸면 아래와 같이 된다.
(headgear 옷들 중 1개를 고르는 경우 + headgear를 아예 선택하지 않는 경우) * (eyewear 옷들 중 1개를 고르는 경우 + eyewear를 아예 선택하지 않는 경우) - (아무것도 입지 않는 경우)처음 접근법도 틀린건 아니지만, 거기에만 매몰돼서 '이 복잡한걸 어떻게 구현하지?' 라는 생각에 막막했던 것 같다. 복잡한 문제를 마주하면 이를 단순하게 바꿔보자!
- 옷 종류 중 1개를 선택하는 경우