주사위는 제한 조건을 제외하고는 어떠한 규칙을 찾을 수 없습니다. 또한 주사위의 최대 개수가 10개이므로 완전 탐색으로 해결할 수 있을거 같습니다. 시간 복잡도를 계산해서 완전 탐색으로 해결할 수 있는지 확인해보겠습니다.
시간 복잡도를 확인하기 전에 테스크를 나누고 각 테스크의 시간 복잡도를 계산해보겠습니다. 테스크를 크게 2개로 나누어야 합니다.
A가 가질 수 있는 주사위의 조합 구하기
가져간 주사위를 굴려서 나올 수 있는 결과 구하기
A가 가질 수 있는 주사위의 조합 구하기
A가 가질 수 있는 주사위의 조합을 구하기 위해서는 Combination을 사용해야 합니다. n이 최대 10이므로 주사위 10개 중에 5개를 고르는 경우의 수는 252입니다.
저는 백트래킹을 활용해서 조합을 구했습니다.
1 2 3 4 5 6 7 8 9 10 11
publicvoidcombination(int n, int k, int[][] dice){ if(n == N/2){ // 2번 과정 return; } for(int i = k; i < N; i++){ visit[i] = true; combination(n+1, i+1, dice); visit[i] = false; } }
n은 현재까지 고른 주사위의 개수이고 k는 현재 고를 수 있는 주사위의 시작 인덱스입니다. k를 사용한 이유는 조합에서는 중복을 허용하지 않기 때문에 다음 주사위를 고를 때 현재 고른 주사위의 다음 인덱스부터 고를 수 있도록 했습니다.
visit을 사용해서 현재 고른 주사위를 표시했습니다.
가져간 주사위를 굴려서 나올 수 있는 결과 구하기
시간 복잡도 미고려
A, B가 가져간 주사위 조합마다 모두 굴려서 나올 수 있는 결과를 구해야 합니다. 그런 다음 A가 이기는 경우의 수를 구해야 합니다. 만일 모든 경우의 수를 구한다면, 주사위 면의 수가 6이므로 O(6^N)가 됩니다. N은 최대 10이므로 6^10 = 60,466,176 입니다. 하지만 주사위의 조합과 함께 고려한다면 60,466,176 * 252 = 15,237,476,352로 시간 초과가 발생 합니다.
시간 복잡도 고려
시간 복잡도를 줄이기 위해서 나올 수 있는 결과를 A, B를 함께 고려하지 않고 A, B 따로 구합니다. 그렇게 되면 A결과 합 중복 조합과 B결과 합 중복 조합을 따로 구하게 됩니다. 그러고 나서 A의 각 합을 이분탐색을 활용해서 B의 결과 보다 큰 경우의 수의 합을 구하면 그게 A가 이기는 경우의 수가 됩니다.
시간 복잡도는 O(NlogN)으로 N은 n이 최대 10일 때 6^5 = 7,776으로 시간 초과가 발생하지 않습니다.