intro : 순열과 조합을 떠올려야 하는 문제인지는 몰랐다.
문제
오늘도 서준이는 알고리즘의 수행시간 수업 조교를 하고 있다. 아빠가 수업한 내용을 학생들이 잘 이해했는지 문제를 통해서 확인해보자. 입력의 크기 n이 주어지면 MenOfPassion 알고리즘 수행 시간을 예제 출력과 같은 방식으로 출력해보자.
MenOfPassion 알고리즘은 다음과 같다.
MenOfPassion(A[], n) {
sum <- 0;
for i <- 1 to n - 2
for j <- i + 1 to n - 1
for k <- j + 1 to n
sum <- sum + A[i] × A[j] × A[k]; # 코드1
return sum;
}
입력
첫째 줄에 입력의 크기 n(1 ≤ n ≤ 500,000)이 주어진다.
출력
첫째 줄에 코드1 의 수행 횟수를 출력한다. 둘째 줄에 코드1의 수행 횟수를 다항식으로 나타내었을 때, 최고차항의 차수를 출력한다. 단, 다항식으로 나타낼 수 없거나 최고차항의 차수가 3보다 크면 4를 출력한다.
문제 풀이
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long n = Long.parseLong(br.readLine());
System.out.println((n - 2) * (n - 1) * (n) / 6);
System.out.println(3);
}
}
문제 해석
MenOfPassion 알고리즘을 코드로 표현하면 다음과 같다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long n = Long.parseLong(br.readLine());
int count = 0;
for (int i = 1; i <= n - 2; i++) {
for (int j = i + 1; j <= n - 1; j++) {
for (int k = j + 1; k <= n; k++) {
count++;
System.out.println(i + "," + j + "," + k + ",");
}
System.out.println();
}
System.out.println();
}
System.out.println("count = " + count);
}
}
출력결과도 같이 한번 보자.
7
1,2,3,
1,2,4,
1,2,5,
1,2,6,
1,2,7,
1,3,4,
1,3,5,
1,3,6,
1,3,7,
1,4,5,
1,4,6,
1,4,7,
1,5,6,
1,5,7,
1,6,7,
2,3,4,
2,3,5,
2,3,6,
2,3,7,
2,4,5,
2,4,6,
2,4,7,
2,5,6,
2,5,7,
2,6,7,
3,4,5,
3,4,6,
3,4,7,
3,5,6,
3,5,7,
3,6,7,
4,5,6,
4,5,7,
4,6,7,
5,6,7,
count = 35
출력결과를 보니 무언가 떠오르지 않는가? 이건 순열과 조합에서 조합의 경우의 수를 보는 것과 같다. 조합의 경우의 수를 구하는 공식은 다음과 같다.

예제에서 7
이 입력값으로 주어졌을때, 35
가 출력값으로 나온 이유는 다음과 같은 계산 과정을 통해 도출 할 수 있다.
계산 과정1
(7 * 6 * 5 * 4 * 3 * 2 * 1)
(4 * 3 * 2 * 1) * (3 * 2 * 1)
계산 과정2
(7 * 6 * 5)
(3 * 2 * 1)
계산 과정3
35
위 과정을 공식으로 도출하면 다음과 같다.
(n * n -1 * n - 2) / 6
여기서 6
으로 나누는 이유가 궁금할 수 있는데, 문제에서 주어진 반복문의 depts는 총 3
회이다. 결국 7
개의 숫자 중에서 3
개를 뽑는 조합의 경우의 수
를 구하는 조건으로 한정시켜 바라볼 수 있기에 6
으로 나눈다.