Skip to content

Commit 5d172f4

Browse files
authored
Merge pull request #1046 from AlgorithmWithGod/0224LJH
[20251005] PGM / LV3 / 주사위 고르기 / 이종환
2 parents e63a99e + e197807 commit 5d172f4

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
```java
2+
import java.io.*;
3+
import java.util.*;
4+
//10C2 라고 해봤자 45임.-> 모든 경우를 다 시도해볼 수 있는 것.
5+
// 특정 케이스에서, sum[i]를 통해서 주사위의 합이 i가 되는게 몇번 있는 지 확인
6+
// 이걸 확인한 후, 상대방의 sum[]에서 이게 어디쯤 위치하는 지를 확인.
7+
// 확인 시 상대방의 sum[1]부터 해서 누적합식으로 승/무/패를 적립하면 됨. 굿.
8+
9+
// 예를 들어 mySum[300]을 구하는거면 counterSum[]의 0~299의 합은 승리수 , counterSum[300]은 무승부 수,
10+
// 전체에서 저 둘을 뺀 값을 패배수가 됨.
11+
// 전체는 이렇게하면 최악의 경우 한쪽 합이 6^5 == 7500?쯤 되는데, 이걸로 진행하면 문제 없다.
12+
// 한번 완탐에 결국 n -> 7500*45 정도 -> 무난.
13+
14+
class Solution {
15+
16+
static double maxWinRate = 0.0;
17+
static int[] ans;
18+
static Dice[] dices;
19+
static Dice[] mine;
20+
static Dice[] rival;
21+
22+
static int diceCnt,halfCnt;
23+
static HashSet<Dice> combSet;
24+
25+
static class Dice{
26+
int idx;
27+
int[] nums= new int[6];
28+
public Dice(int idx, int[] arr){
29+
this.idx = idx;
30+
nums = arr;
31+
}
32+
}
33+
34+
35+
36+
public int[] solution(int[][] dice) {
37+
diceCnt = dice.length;
38+
halfCnt = diceCnt/2;
39+
dices = new Dice[diceCnt];
40+
41+
mine = new Dice[halfCnt];
42+
rival = new Dice[halfCnt];
43+
ans = new int[halfCnt];
44+
combSet = new HashSet<>();
45+
46+
for (int i = 0; i < diceCnt; i++){
47+
int[] input = dice[i];
48+
dices[i] = new Dice(i, input);
49+
}
50+
51+
processCombination();
52+
53+
return ans;
54+
}
55+
56+
private void calculate(){
57+
int[] myResult = getSumArr(mine);
58+
int[] rivalResult = getSumArr(rival);
59+
60+
long rTotal = 0;
61+
for (int i = 0; i <= 600; i++)rTotal += rivalResult[i];
62+
63+
double win = 0;
64+
double draw = 0;
65+
double lose = 0;
66+
int rCumulSum = 0;
67+
68+
for (int i = 0 ; i <= 600; i++){
69+
rCumulSum += rivalResult[i];
70+
71+
if (myResult[i] == 0) continue;
72+
73+
int cur = myResult[i];
74+
int rivalCur = rivalResult[i];
75+
76+
win += (rCumulSum - rivalCur) * cur;
77+
draw += (rivalCur) * cur;
78+
lose += (rTotal - rCumulSum) * cur;
79+
80+
}
81+
82+
double winRate = win / (win+draw+lose);
83+
if (winRate > maxWinRate){
84+
for (int i = 0; i < halfCnt; i++){
85+
ans[i] = mine[i].idx+1;
86+
// System.out.print(mine[i].idx + " ");
87+
}
88+
// System.out.println (" -> "+ win + " " + draw + " "+ lose);
89+
maxWinRate = winRate;
90+
}
91+
92+
93+
}
94+
95+
96+
private int[] getSumArr(Dice[] d){
97+
int[] dp = new int[601];
98+
int[] ex = new int[601];
99+
ex[0] = 1;
100+
101+
for (int tr = 0; tr < halfCnt; tr++){
102+
for (int i =0; i <= 600; i++){
103+
if (ex[i] != 0){
104+
for (int j = 0; j < 6; j++){
105+
if ( i + d[tr].nums[j] <= 600) dp[i+d[tr].nums[j]] += ex[i];
106+
}
107+
}
108+
}
109+
110+
ex = dp;
111+
dp = new int[601];
112+
}
113+
114+
return ex;
115+
116+
}
117+
118+
private void makeDiceArr(){
119+
int idx = 0;
120+
int rIdx = 0;
121+
for (int i = 0 ; i < diceCnt; i++){
122+
if (combSet.contains(dices[i])){
123+
mine[idx++] = dices[i];
124+
} else{
125+
rival[rIdx++] = dices[i];
126+
}
127+
}
128+
}
129+
130+
131+
132+
private void combination(int curSize, int idx){
133+
if ( curSize == halfCnt){
134+
makeDiceArr();
135+
calculate();
136+
return;
137+
}
138+
139+
for (int i = idx+1; i < diceCnt; i++){
140+
combSet.add(dices[i]);
141+
combination(curSize+1,i);
142+
combSet.remove(dices[i]);
143+
}
144+
}
145+
146+
private void processCombination(){
147+
combination(0,-1);
148+
}
149+
150+
151+
152+
153+
154+
155+
156+
}
157+
```

0 commit comments

Comments
 (0)