Skip to content

Conversation

@mj010504
Copy link
Collaborator

๐Ÿ”— ๋ฌธ์ œ ๋งํฌ

์ฃผ์‚ฌ์œ„ ๊ณ ๋ฅด๊ธฐ
https://school.programmers.co.kr/learn/courses/30/lessons/258709

โœ”๏ธ ์†Œ์š”๋œ ์‹œ๊ฐ„

1์‹œ๊ฐ„

์—ฌ๋‹ด

  • ๋ฌธ์ œ๊ฐ€ ๋‹จ์ˆœํ•˜๋ฉด์„œ๋„ ๊ตฌํ˜„ํ•  ๊ฒƒ์ด ๋งŽ์•„ ๋ณต์žกํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•œ ๋ฌธ์ œ์•ˆ์—์„œ ์—ฌ๋Ÿฌ ๋ฌธ์ œ๋ฅผ ํ‘ผ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹œ๊ณ  ๋„์ „ํ•ด๋ณด์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

โœจ ์ˆ˜๋„ ์ฝ”๋“œ

  • A์™€ B๊ฐ€ n๊ฐœ์˜ ์ฃผ์‚ฌ์œ„ ์ค‘์— n / 2๊ฐœ์˜ ์ฃผ์‚ฌ์œ„๋ฅผ ๊ฐ๊ฐ ๊ณจ๋ผ์„œ ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๋น„๊ตํ•ด ์Šน๋ฅ ์„ ๊ณ„์‚ฐํ•˜์—ฌ ๊ฐ€์žฅ ์Šน๋ฅ ์ด ๋†’์€ ์ฃผ์‚ฌ์œ„ ์กฐํ•ฉ์„ ๊ตฌํ•ด์•ผํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ด๋•Œ ์กฐํ•ฉ์„ ๊ตฌํ˜„ํ•˜์—ฌ ๋น„๊ตํ•ด๋ณผํ…๋ฐ ์‹ค์ œ๋กœ ๋ˆ„๊ฐ€ ์Šน๋ฅ ์ด ๋†’์€๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹น์—ฐํžˆ A๋˜๋Š” B๊ฐ€ ์Šน๋ฅ ์ด ๋†’์„ ๊ฒƒ์ด๊ณ  ์šฐ๋ฆฌ๋Š” ๊ฐ€์žฅ ์Šน๋ฅ ์ด ๋†’์€ ์กฐํ•ฉ์„ ๊ตฌํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

  • ์ฒ˜์Œ์—๋Š” ์ฃผ์‚ฌ์œ„ ํ•„์Šน์กฐํ•ฉ์„ ๊ตฌํ• ๋ ค๋ฉด ์ฃผ์‚ฌ์œ„ ํ•ฉ๋“ค์˜ ํ‰๊ท ์„ ๋น„๊ตํ•ด์•ผ ํ• ๊นŒ๋„ ์ƒ๊ฐํ•ด๋ดค๋Š”๋ฐ ๊ทธ๋Ÿฐ์‹์œผ๋กœ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฌธ์ œ๋Š” ์—ฌํƒœ๊นŒ์ง€ ๋งŽ์ด ์—†์—ˆ๋˜ ๊ฒƒ ๊ฐ™๊ณ , ๋‹น์—ฐํžˆ ๋ชจ๋“  ์ฃผ์‚ฌ์œ„ ์กฐํ•ฉ์— ๋”ฐ๋ฅธ ์Šน๋ถ€์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•ด์•ผํ•  ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค. ์ตœ์•…์˜ ๊ฒฝ์šฐ ์ฃผ์‚ฌ์œ„๊ฐ€ 10๊ฐœ์ผ ๋•Œ 10C5 * 6^5์ •๋„์˜ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ ๋‚˜์˜ฌ ๊ฒƒ ๊ฐ™์•˜๊ณ  ์ง์ ‘ ๊ณ„์‚ฐํ•ด๋ณด์ง€๋Š” ์•Š์•˜์ง€๋งŒ ๋‹ค๋ฅธ ํ’€์ด ๋ฐฉ๋ฒ•๋„ ๋– ์˜ค๋ฅด์ง€ ์•Š์•„ ํ’€์ด์— ๋“ค์–ด๊ฐ”์Šต๋‹ˆ๋‹ค.

  • ์šฐ์„  n / 2๊ฐœ์”ฉ ์ฃผ์‚ฌ์œ„๋ฅผ ๋‚˜๋ˆ ๊ฐ€์ง€๋Š” ๋ชจ๋“  ์กฐํ•ฉ์„ ๊ตฌํ•˜๋Š” pickDice ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ์กฐํ•ฉ์€ ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ–ˆ๊ณ  ํ•œ ๋ฒˆ ์‚ฌ์šฉํ–ˆ๋˜ ์กฐํ•ฉ๋“ค์€ ๋‹ค์‹œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด Set<Set>๋ฅผ ๋งŒ๋“ค์–ด ์ค‘๋ณต์„ ๋ฐฉ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ €๋ฒˆ์— ์™„์ „๋ฒ”์ฃ„ ๋ฌธ์ œ์—์„œ set<tuple<int, int, int>>๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋Š”๋ฐ Set<Set>๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์›ฌ๋งŒํ•œ ๋ฌธ์ œ์—์„œ DFS + ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ฃผ์‚ฌ์œ„๋ฅผ ๊ฐ์ž ๋‚˜๋ˆ ๊ฐ€์ง€๊ณ  ๋ชจ๋“  ํ•ฉ๋“ค์„ ๊ตฌํ•ด์•ผํ•  ํ…๋ฐ getDiceSum() ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ชจ๋“  ํ•ฉ๋“ค์„ ๊ฐ๊ฐ ๋ฐฐ์—ด(sumA, sumB)์— ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ sumA ๋ฐ sumB๋ฅผ ์ €๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ํ•ฉ๋“ค์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  • ์ด์ œ ์ฃผ์‚ฌ์œ„์˜ ์กฐํ•ฉ์— ๋”ฐ๋ฅธ ๋ชจ๋“  ํ•ฉ๋„ ๊ตฌํ•ด์กŒ์œผ๋ฏ€๋กœ ๋ชจ๋“  ๊ฐ’์„ ๊ฐ๊ฐ ๋น„๊ตํ•ด์„œ ์Šน๋ฆฌ ํšŸ์ˆ˜ ์™€ ํŒจ๋ฐฐ ํšŸ์ˆ˜๋ฅผ ๊ตฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ์—์„œ ๊ฐ€์žฅ ๋†’์€ ์Šน๋ฅ ์ด๋ž€ ๊ฒฝ๊ธฐ ํšŸ์ˆ˜๋Š” ๋ฌด์กฐ๊ฑด ๋™์ผํ•˜๋ฏ€๋กœ ์Šน๋ฆฌ ํšŸ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ๋งŽ๊ฑฐ๋‚˜, ์Šน๋ฆฌ ํšŸ์ˆ˜๊ฐ€ ๊ฐ™๋‹ค๋ฉด ํŒจ๋ฐฐ ํšŸ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ์ ์€ ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ ์Šน๋ฆฌ ํšŸ์ˆ˜์™€ ํŒจ๋ฐฐ ํšŸ์ˆ˜๋ฅผ ๋ชจ๋‘ ๊ตฌํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” maxRate๋ผ๋Š” pair<int, int> ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ฐ๊ฐ ์Šน๋ฆฌ์™€ ํŒจ๋ฐฐ์ˆ˜๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ตœ๊ณ ์˜ ์Šน๋ฅ ์— ๋”ฐ๋ฅธ ์Šน๋ฆฌ ์ˆ˜์™€ ํŒจ๋ฐฐ์ˆ˜ ๊ฐ’์„ ๊ฐฑ์‹ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ’์„ ๊ฐฑ์‹ ํ•ด์ฃผ๋ฉด์„œ ์ด ๋ฌธ์ œ์˜ ๋‹ต์ธ A๊ฐ€ ์Šน๋ฅ ์ด ๊ฐ€์žฅ ๋†’์€ ์ฃผ์‚ฌ์œ„ ์กฐํ•ฉ maxA๋„ ๊ฐฑ์‹ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๋‹ด

  • ํ’€์ด๊ฐ€ ๋‹ค์–‘ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์€๋ฐ์š”. ์ œ ํ’€์ด์— ๋น„ํšจ์œจ์ ์ธ ๋ถ€๋ถ„์ด ์žˆ๊ฑฐ๋‚˜ ๋‹ค๋ฅด๊ฒŒ ์ƒ๊ฐํ•œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ๋งŽ์€ ์ง€์  ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๐Ÿ“š ์ƒˆ๋กญ๊ฒŒ ์•Œ๊ฒŒ๋œ ๋‚ด์šฉ

@hyeokbini
Copy link
Collaborator

๊ตฌํ˜„ํ•ด์•ผ ํ•  ๋ถ€๋ถ„์ด ๋งŽ์•„์„œ ๋งŽ์ด ์–ด์ง€๋Ÿฌ์› ๋„ค์š”. ์ €๋Š” ์ „์ฒด์ ์œผ๋กœ 2๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ ์„œ ํ’€์ด๋ฅผ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

  1. ์ฃผ์‚ฌ์œ„์˜ ์ ˆ๋ฐ˜์„ ๊ฐ€์ ธ๊ฐ€๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋Œ€๋กœ ์ธ๋ฑ์Šค ๋ฒกํ„ฐ ๋งŒ๋“ค๊ธฐ
  2. ์ธ๋ฑ์Šค ๋ฒกํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ€์ง„ ์ฃผ์‚ฌ์œ„์—์„œ ๋‚˜์˜ค๋Š” ํ•ฉ์˜ ๋ฒกํ„ฐ๋ฅผ ๋งŒ๋“ค๊ณ , ์Šน๋ฅ  ๊ณ„์‚ฐํ•˜๊ธฐ

1๋ฒˆ์€ ๊ฐ„๋‹จํ•œ ์žฌ๊ท€ํ•จ์ˆ˜ ์กฐํ•ฉ์„ ํ†ตํ•ด ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. A์ฃผ์‚ฌ์œ„์— ๋“ค์–ด๊ฐˆ N/2๊ฐœ๋ฅผ ๋ฝ‘์€ ํ›„, ๋ฒกํ„ฐ ๊ธธ์ด๊ฐ€ N/2๊ฐ€ ๋œ๋‹ค๋ฉด ์„ ํƒ๋˜์ง€ ์•Š์€ ๊ฒƒ๋“ค์„ B์ฃผ์‚ฌ์œ„ ๋ฒกํ„ฐ์— ๋„ฃ์–ด์„œ checkํ•จ์ˆ˜์— ๋‘ ๋ฒกํ„ฐ๋ฅผ ๋„˜๊ฒจ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

2๋ฒˆ์ด ์กฐ๊ธˆ ๊นŒ๋‹ค๋กœ์› ๋Š”๋ฐ, ์šฐ์„  ๋ชจ๋“  ์ฃผ์‚ฌ์œ„์˜ ๋ˆˆ์˜ ํ•ฉ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋•Œ ๋ˆ„์ ํ•ด์„œ ํ•ฉ์„ ๊ฐฑ์‹ ํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด๋ดค๋Š”๋ฐ,

vector<int> arolls = {0};

for (int i = 0; i < (int)adice.size(); ++i)
    {
        int idx = adice[i];
        vector<int> temp;
        for (int j = 0; j < (int)dice[idx].size(); ++j)
        {
            int roll = dice[idx][j];
            for (int k = 0; k < (int)arolls.size(); ++k)
            {
                temp.push_back(arolls[k] + roll);
            }
        }
        arolls = move(temp);
    }

์˜ˆ์‹œ๋ฅผ ๋“ค์–ด ํ•จ์ˆ˜์˜ ์ž‘๋™ ๋ฐฉ์‹์„ ์„ค๋ช…ํ•œ๋‹ค๋ฉด,
adice = 0,1
dice[0] = 1,2
dice[1] = 3,4
์ธ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

arolls์— 0์„ ๊ธฐ๋กํ•œ ๋’ค, ํ•œ ์ฃผ์‚ฌ์œ„์— ๋Œ€ํ•ด arolls[๋ชจ๋“  ์ธ๋ฑ์Šค] + adice[i][j] ๊ฐ’์„ temp๋ฒกํ„ฐ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์ฒซ๋ฒˆ์งธ ์ฃผ์‚ฌ์œ„

arolls[0] = 0 -> temp.push_back(0 + 1(dice[0][0])) -> temp = {1}
arolls[0] = 0 -> temp.push_back(0 + 2(dice[0][1])) -> temp = {1,2}

arolls = move(temp) -> arolls = {1,2}

๋‘๋ฒˆ์งธ ์ฃผ์‚ฌ์œ„

arolls[0] = 1 -> temp.push_back(1+3(dice[1][0])) โ†’ temp = {4}
arolls[1] = 2 -> temp.push_back(2+3(dice[1][0])) โ†’ temp = {4,5}

arolls[0] = 1 -> temp.push_back(1+4(dice[1][1])) โ†’ temp = {4,5,5}
arolls[1] = 2 -> temp.push_back(2+4(dice[1][1])) โ†’ temp = {4,5,5,6}

arolls = move(temp) -> arolls = {4,5,5,6}

....

์ด๋Ÿฐ ์‹์œผ๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ์กฐํ•ฉ๋“ค์— ๋Œ€ํ•ด ์Šน๋ฅ ์„ ๋น„๊ตํ•ด์•ผ ํ•˜๋Š”๋ฐ, ๋‹จ์ˆœํžˆ 2์ค‘ for๋ฌธ์œผ๋กœ ๋น„๊ตํ•˜๋ฉด O(N^2)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ผ ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋‚  ์ˆ˜๋„ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋‘ ๋ฒกํ„ฐ๋ฅผ ์ •๋ ฌํ•œ ํ›„ ํˆฌ ํฌ์ธํ„ฐ ๊ฐœ๋…์„ ์‚ฌ์šฉํ•ด์„œ ๋น„๊ตํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. 2์ค‘for๋ฌธ์„ ์“ฐ๋Š” ๋ฐฉ์‹์„ ํ…Œ์ŠคํŠธํ•ด๋ณด์ง„ ์•Š์•„์„œ ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๊ฑธ๋ฆด์ง€๋Š” ๋ชจ๋ฅด๊ฒ ๋„ค์š”. ์šฐ์„  ํˆฌํฌ์ธํ„ฐ ๋ฐฉ์‹์€ ์•„์Šฌ์•„์Šฌํ•˜๊ธด ํ•˜์ง€๋งŒ ์ •๋‹ต์„ ๋ฐ›๊ธด ํ–ˆ์Šต๋‹ˆ๋‹ค.

image

์ด๋ ‡๊ฒŒ ์—ด์‹ฌํžˆ ๊ตฌํ˜„ํ•ด๋†“๊ณ  ๋˜ 1 based index์ธ๊ฑฐ ๋†“์ณ์„œ ์˜ค๋‹ต ํ•œ๋ฒˆ ๋ฐ›์•˜๋„ค์š”. ํ•ญ์ƒ ์ฃผ์˜ํ•˜๋ ค ํ•˜์ง€๋งŒ ํ•ญ์ƒ ๋†“์น˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋” ์ฃผ์˜ํ•ด์•ผ๊ฒ ๋„ค์š”.

์•„๋ž˜๋Š” ์ œ์ถœ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์˜ค๋žœ๋งŒ์— ์•ˆ ์“ฐ๋˜ ๊ฐœ๋…๋“ค์„ ์“ฐ๋ ค๋‹ˆ ๋จธ๋ฆฌ๊ฐ€ ๋”ฐ๋œปํ•ด์ง„ ๋ฌธ์ œ์˜€๋„ค์š”. ํ‘ธ์‹œ๋А๋ผ ๊ณ ์ƒํ•˜์…จ์–ด์š”! ๐Ÿ˜Ž

์ฃผ์‚ฌ์œ„ ๊ณ ๋ฅด๊ธฐ / c++
#include <bits/stdc++.h>
using namespace std;

vector<int> ans;
double maxWinRate = 0.0;

void check(vector<vector<int>> &dice, vector<int> adice, vector<int> bdice) {
    vector<int> arolls = {0};
    vector<int> brolls = {0};

    //  ์กฐํ•ฉ์˜ ๋ชจ๋“  ํ•ฉ
    for (int i = 0; i < (int)adice.size(); i++)
    {
        int idx = adice[i];
        vector<int> temp;
        for (int j = 0; j < (int)dice[idx].size(); j++)
        {
            int roll = dice[idx][j];
            for (int k = 0; k < (int)arolls.size(); k++)
            {
                temp.push_back(arolls[k] + roll);
            }
        }
        arolls = move(temp);
    }

    for (int i = 0; i < (int)bdice.size(); i++)
    {
        int idx = bdice[i];
        vector<int> temp;
        for (int j = 0; j < (int)dice[idx].size(); j++)
        {
            int roll = dice[idx][j];
            for (int k = 0; k < (int)brolls.size(); k++)
            {
                temp.push_back(brolls[k] + roll);
            }
        }
        brolls = move(temp);
    }

    // ์ •๋ ฌ ํ›„ ํˆฌํฌ์ธํ„ฐ๋กœ A๊ฐ€ ์ด๊ธฐ๋Š” ๊ฒฝ์šฐ ๊ณ„์‚ฐ
    sort(arolls.begin(), arolls.end());
    sort(brolls.begin(), brolls.end());

    long long winCount = 0;
    int j = 0;
    for (int i = 0; i < (int)arolls.size(); i++)
    {
        while (j < (int)brolls.size() && brolls[j] < arolls[i])
        {
            j++;
        }
        winCount += j;
    }

    long long totalCount = (long long)arolls.size() * brolls.size();
    double winRate = (double)winCount / totalCount;

    // ์ตœ๊ณ  ์Šน๋ฅ ์ด๋ฉด ๊ฐฑ์‹ 
    if (winRate > maxWinRate)
    {
        maxWinRate = winRate;
        ans = adice;
    }
}


void choose(vector<vector<int>> &dice, vector<int> adice, vector<int> bdice, int dicecount, int start)
{
    if (adice.size() == dicecount / 2)
    {
        for (int i = 0; i < dicecount; i++)
        {
            if (std::find(adice.begin(), adice.end(), i) == adice.end())
            {
                bdice.push_back(i);
            }
        }
        check(dice, adice, bdice);
        return;
    }

    for (int i = start; i < dicecount; i++)
    {
        adice.push_back(i);
        choose(dice, adice, bdice, dicecount, i + 1);
        adice.pop_back();
    }
}


vector<int> solution(vector<vector<int>> dice) {
    vector<int> adice;
    vector<int> bdice;
    choose(dice,adice,bdice,dice.size(),0);
    for(auto &i : ans)
    {
        i++;
    }
    return ans;
}

Copy link
Collaborator

@Seol-Munhyeok Seol-Munhyeok left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์‰ฝ๊ฒŒ ํ’€๋ฆด ๊ฑฐ ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๋ฌธ์ œ ์ค‘์—์„œ ์ง„์งœ ์–ด๋ ค์šด ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค...

๋จผ์ € ๋ธŒ๋ฃจํŠธํฌ์Šค๋กœ ํ’€ ๋•Œ, ์ตœ์•…์˜ ์—ฐ์‚ฐํšŸ์ˆ˜๋ฅผ ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค.

$n=10$ ์ผ ๋•Œ, 10๊ฐœ ์ค‘ 5๊ฐœ๋ฅผ ๋ฝ‘์•„์„œ ์ฃผ์‚ฌ์œ„๋ฅผ ๋‚˜๋ˆ„๊ณ , A, B๊ฐ€ ๊ฐ€์ง„ ์ฃผ์‚ฌ์œ„ 10๊ฐœ์— ๋Œ€ํ•ด์„œ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋Š” ์ฃผ์‚ฌ์œ„ ๋ˆˆ ์กฐํ•ฉ์„ ๊ณฑํ•˜๋ฉด ๋˜๋‹ˆ๊นŒ
$10C5 \times 6^{10} = 15237476352 = 152์–ต$
๊ฐ€ ๋‚˜์™€์„œ ์ ˆ๋Œ€ ์ด ๋ฐฉ๋ฒ•์€ ์•ˆ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ ๋ณต์žก๋„๋ฅผ ์ค„์ผ๊นŒ๋ฅผ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ DP๊ฐ€ ๋– ์˜ฌ๋ž๋Š”๋ฐ
$dp[i][j] =$ $i$ ๋ฒˆ์งธ ์ฃผ์‚ฌ์œ„๊นŒ์ง€ ์‚ดํŽด๋ณผ ๋•Œ, ํ•ฉ์ด $j$๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜
๋กœ ์ •์˜ํ•˜๊ณ  ์ดˆ๊ธฐ๊ฐ’์„ $dp[0][0] = 1$๋กœ ์ค๋‹ˆ๋‹ค.
์•„์ง ์•„๋ฌด ์ฃผ์‚ฌ์œ„๋„ ์•ˆ ๋˜์กŒ์„ ๋•Œ, ํ•ฉ์ด 0์ด ๋˜๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ 1์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.
์™„์ „ ๋ฒ”์ฃ„ ๋ฌธ์ œ๋ž‘ ์œ ์‚ฌํ•œ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ ํ™”์‹์ด
image

์ด ๋ฉ๋‹ˆ๋‹ค. ์‹์ด๋ผ ๋ณต์žกํ•œ๋ฐ ๋ง๋กœ ์„ค๋ช…ํ•˜๋ฉด
์ด๋ฒˆ ์ฃผ์‚ฌ์œ„์—์„œ $j$๊ฐ€ ๋‚˜์˜ค๋ฉด, ์ด์ „๊นŒ์ง€ ํ•ฉ์€ $jโˆ’v$ ์—ฌ์•ผ ํ•œ๋‹ค ๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
dp ๋ฌธ์ œ ์ค‘์— 1, 2, 3๋งŒ ๋”ํ•ด์„œ ํŠน์ • ์ˆซ์ž ๋งŒ๋“œ๋Š” ๋ฌธ์ œ๋ž‘ ๋น„์Šทํ•œ ๋…ผ๋ฆฌ์ž…๋‹ˆ๋‹ค.


๊ทผ๋ฐ ์‚ฌ์‹ค ์ด๋ ‡๊ฒŒ ํ•  ํ•„์š”๊ฐ€ ์ „ํ˜€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฏผ์ค€ ๋‹˜ ํ’€์ด๋Š” ๊ทธ๋ƒฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์œผ๋กœ for ๋ฌธ์œผ๋กœ ๋ชจ๋“  ์ฃผ์‚ฌ์œ„ ๋ˆˆ์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š”๋ฐ ์™œ ํ†ต๊ณผ๊ฐ€ ๋˜๋Š”์ง€ ์ƒ๊ฐํ•ด๋ดค๋Š”๋ฐ, ์ œ๊ฐ€ ์—ฐ์‚ฐ ํšŸ์ˆ˜๋ฅผ ์ž˜๋ชป ๊ณ„์‚ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์‚ฌ์œ„ ๋ˆˆ์˜ ํ•ฉ์„ A ํ•ฉ ๋”ฐ๋กœ B ํ•ฉ ๋”ฐ๋กœ ๊ตฌํ•˜๋Š” ๊ฑฐ๋‹ˆ๊นŒ ๋‘˜์„ ๊ณฑํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ๋”ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
์ •ํ™•ํ•œ ์—ฐ์‚ฐํšŸ์ˆ˜๋ฅผ ๊ตฌํ•˜๋ฉด $10C5 \times (6^{5} + 6^{5})= 3919104 = 391๋งŒ$
์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ทธ๋ƒฅ ๊ตฌํ•ด๋„ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค...


์•„๋ฌดํŠผ DP๋กœ A์™€ B์˜ ์ฃผ์‚ฌ์œ„ ๋ˆˆ์˜ ํ•ฉ์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๋‹ด์€ ๋ฐฐ์—ด์„ ๊ตฌํ•˜๊ณ 
B์˜ ๋ˆ„์ ํ•ฉ ๋ฐฐ์—ด์„ ํ†ตํ•ด์„œ A๊ฐ€ ์ด๊ธฐ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ตฌํ–ˆ์Šต๋‹ˆ๋‹ค.
image

A[i], B[i]๋Š” A ๋˜๋Š” B๊ฐ€ ์ฃผ์‚ฌ์œ„๋ฅผ ๋˜์ ธ์„œ ํ•ฉ์„ i๋กœ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜์ด๊ณ 
A๊ฐ€ ์ด๊ธฐ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋Š” A[i] > 0 ์ผ ๋•Œ, A[i] * (B[1] + B[2] + ... + B[i-1])๋ฅผ ๋ชจ๋“  i์— ๋Œ€ํ•ด ๋”ํ•œ ๊ฐ’์ด ๋ฉ๋‹ˆ๋‹ค.
๋งค๋ฒˆ B[1] + B[2] + ... + B[i-1]๋ฅผ ์ง์ ‘ ๊ตฌํ•˜๋ฉด ์‹œ๊ฐ„์ดˆ๊ณผ์˜ ์œ„ํ—˜์ด ์žˆ์œผ๋ฏ€๋กœ ๋ˆ„์ ํ•ฉ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.


์ฃผ์‚ฌ์œ„ ๊ตด๋ฆฌ๊ธฐ
from itertools import combinations

def solve(dice_set):
    n = len(dice_set)
    max_value = sum(max(d) for d in dice_set)
    dp = [[0] * (max_value+1) for _ in range(n+1)]
    dp[0][0] = 1
    
    for i, faces in enumerate(dice_set, start=1):
        for s in range(max_value+1):
            for v in faces:
                if s + v <= max_value:
                    dp[i][s + v] += dp[i-1][s]
    
    return dp[n]
    
def solution(dice):
    answer = []
    max_count = -1
    n = len(dice)
    combs = combinations(range(n), n // 2)
    
    for comb in combs:
        # A, B ์ฃผ์‚ฌ์œ„ ์„ ํƒ
        comb_set = set(comb)
        a_dice = [dice[i] for i in range(n) if i in comb_set]
        b_dice = [dice[i] for i in range(n) if i not in comb_set]

        # A, B๊ฐ€ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์ฃผ์‚ฌ์œ„ ํ•ฉ์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜ ๊ตฌํ•˜๊ธฐ
        A = solve(a_dice)
        B = solve(b_dice)
        
        # B ๋ˆ„์ ํ•ฉ ๋ฐฐ์—ด ์ƒ์„ฑ
        m = max(len(A), len(B))
        b_sum = [0] * (m)
        
        if len(B) > 0:
            b_sum[0] = B[0]
        for i in range(1, m):
            b_sum[i] = b_sum[i-1] + (B[i] if i < len(B) else 0)
                
        # A๊ฐ€ ์ด๊ธฐ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜ ๊ณ„์‚ฐ
        count = 0
        for i in range(1, len(A)):
            if A[i]:
                count += A[i] * b_sum[i-1]
        
        # ์ตœ๋Œ“๊ฐ’ ๊ฐฑ์‹ 
        if count > max_count:
            answer = comb
            max_count = count
    
    return [x + 1 for x in answer]  # 1-based

๋‹ค๋ฅธ ํ’€์ด๋ฅผ ๋˜ ์ฐพ์•„๋ณด๋‹ˆ๊นŒ ์ด๋ถ„ํƒ์ƒ‰์„ ์‚ฌ์šฉํ•ด์„œ๋„ ํ’€ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์นด์นด์˜ค ๊ณต์‹ ํ•ด์„ค ์„ ๋ณด๋ฉด

  • A์™€ B์˜ ์ฃผ์‚ฌ์œ„๋ฅผ ํ•œ๊บผ๋ฒˆ์— ๋ชจ๋‘ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ด ์ŠนํŒจ๋ฅผ ํŒ๋‹จํ•˜๋Š” ๋Œ€์‹ , A์™€ B์˜ ์ฃผ์‚ฌ์œ„๋ฅผ ๋”ฐ๋กœ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ํ•˜๊ธฐ
  • ๋ˆ„์  ํ•ฉ, ํˆฌ ํฌ์ธํ„ฐ, ์ด๋ถ„ ํƒ์ƒ‰๋“ฑ์˜ ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ด์„œ ์‹œ๊ฐ„๋ณต์žก๋„ ์ค„์ด๊ธฐ

๊ฐ€ ์ด ๋ฌธ์ œ์˜ ํ•ต์‹ฌ์ธ ๊ฑฐ ๊ฐ™์Šต๋‹ˆ๋‹ค.


์ถ”๊ฐ€์˜๊ฒฌ

๋ฏผ์ค€ ๋‹˜๊ป˜์„œ

"์ด ๋ฌธ์ œ์—์„œ ๊ฐ€์žฅ ๋†’์€ ์Šน๋ฅ ์ด๋ž€ ๊ฒฝ๊ธฐ ํšŸ์ˆ˜๋Š” ๋ฌด์กฐ๊ฑด ๋™์ผํ•˜๋ฏ€๋กœ ์Šน๋ฆฌ ํšŸ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ๋งŽ๊ฑฐ๋‚˜, ์Šน๋ฆฌ ํšŸ์ˆ˜๊ฐ€ ๊ฐ™๋‹ค๋ฉด ํŒจ๋ฐฐ ํšŸ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ์ ์€ ๊ฒƒ์„ ์˜๋ฏธ" ํ•œ๋‹ค๊ณ  ํ•˜์…จ๋Š”๋ฐ,

๋ฌธ์ œ์—์„œ "์Šน๋ฆฌํ•  ํ™•๋ฅ ์ด ๊ฐ€์žฅ ๋†’์€ ์ฃผ์‚ฌ์œ„ ์กฐํ•ฉ์ด ์œ ์ผํ•œ ๊ฒฝ์šฐ๋งŒ ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค." ๋ผ๊ณ  ํ–ˆ์œผ๋ฏ€๋กœ ๊ทธ๊ฒƒ๊นŒ์ง€๋Š” ๊ณ ๋ คํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ €๋Š” ๊ทธ๋ƒฅ ์Šน๋ฅ ์€ ์Šน๋ฆฌํ•  ๊ฒฝ์šฐ์˜ ์ˆ˜ / ์ „์ฒด ๊ฒฝ์šฐ์˜ ์ˆ˜๋ผ ํ•ด์„ํ•˜๊ณ  ํ’€์—ˆ๋Š”๋ฐ ์Šน๋ฅ ์˜ ํ•ด์„์ด ๋ชจํ˜ธํ•ด์ง€๋Š” ๊ฑฐ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ์œ„ํ•ด ์œ„์™€ ๊ฐ™์€ ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•œ ๊ฑฐ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋‹ค๋“ค ๋ฌธ์ œ ํ‘ธ์‹ ๋‹ค๊ณ  ๊ณ ์ƒํ•˜์…จ์Šต๋‹ˆ๋‹ค!

@mj010504
Copy link
Collaborator Author

mj010504 commented Aug 18, 2025

@Seol-Munhyeok ์ข‹์€ ์ง€์ ๋“ค ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ œ๊ฐ€ ์กฐ๊ธˆ ์•ผ๋งค๋กœ ํ‘ผ ๋А๋‚Œ์ด ์žˆ๊ธด ํ•˜๋„ค์š”.

์ž ์ด ์•ˆ์™€์„œ ํˆฌํฌ์ธํ„ฐ๋กœ ํ’€์–ด๋ดค์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด 10๋ฐฐ ์ค„์—ˆ์Šต๋‹ˆ๋‹ค. ํˆฌํฌ์ธํ„ฐ๊ฐ€ ์ง๊ด€์ ์ด๋ผ ์ดํ•ด๊ฐ€ ์‰ฝ๋„ค์š”.

์ฃผ์‚ฌ์œ„ ๊ณ ๋ฅด๊ธฐ(ํˆฌํฌ์ธํ„ฐ)
#include<bits/stdc++.h>

using namespace std;

int n;
vector<vector<int>> dice;
vector<int> picked;
double maxRate = 0.0;
vector<int> maxA;
set<set<int>> s;

void getDiceSum(int idx, vector<int> v, vector<int>& sv) {
        for(int i = 0; i < v.size(); i++) { 
            int idx = v[i];
            vector<int> temp;

            for(int j = 0; j < 6; j++) {
                for(int k = 0; k < sv.size(); k++) {
                    temp.push_back(sv[k] + dice[idx][j]);
                }
            }

            sv = move(temp);
        }
}

void rollDice(vector<int> a, vector<int> b) {
    vector<int> sumA = {0}; getDiceSum(0, a, sumA);
    vector<int> sumB = {0}; getDiceSum(0, b, sumB);
    
    int victoryA = 0;
    int victoryB = 0;
    
    sort(sumA.begin(), sumA.end());
    sort(sumB.begin(), sumB.end());

    int j = 0;
    for(int i = 0; i < sumA.size(); i++) {
        while(j < sumB.size() && sumA[i] > sumB[j]) {
           j++;
        }
        victoryA += j;
    }
    
    j = 0;
     for(int i = 0; i < sumB.size(); i++) {
        while(j < sumA.size() && sumB[i] > sumA[j]) {
            j++;
        }
        victoryB += j;
    }
    
    double winRateA = (double)victoryA / (sumA.size() * sumB.size());
  double winRateB = (double)victoryB / (sumA.size() * sumB.size());
    
   if(winRateA > maxRate) {
       maxRate = winRateA;
       maxA = a;
   }
    
   if(winRateB > maxRate) {
       maxRate = winRateB;
       maxA = b;
   }

}

void pickDice(int cnt, int idx) {
    if(cnt == n / 2) {
        vector<int> a; vector<int> b;
        for(int i = 0; i < n; i++) {
            if(picked[i]) a.push_back(i);
            else b.push_back(i);
        }

        set<int> as(a.begin(), a.end());
        set<int> bs(b.begin(), b.end());

        if(!s.count(as)) {
            rollDice(a, b);
            s.insert(as); s.insert(bs);
        }
        
        
    }
    else {
        for(int i = idx; i < n; i++) {
            if(!picked[i]) {
                picked[i] = true;
                pickDice(cnt + 1, i + 1);
                picked[i] = false;
            }
        }
    }
}

vector<int> solution(vector<vector<int>> dv) {
    n = dv.size();
    dice = dv;
    picked.resize(n, false);
    pickDice(0, 0);

    for(int i = 0; i < maxA.size(); i++) {
        maxA[i]++;
    }

    return maxA;
}

Copy link
Collaborator

@flydongwoo flydongwoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR๊ณผ ๋ฆฌ๋ทฐ๋ฅผ ๋ณด๊ธฐ ์ „, ๋จผ์ € ๋„์ „ํ•ด๋ดค๋Š”๋ฐ ์™€ ์ง„์งœ ๊ตฌํ˜„ํ•  ๊ฒƒ๋„ ๋งŽ๊ณ  ์–ด๋ ค์› ๋„ค์š”
์—ญ์‹œ ์ „ ์•„์ง ๋งŽ์ด ๋ถ€์กฑํ•œ๊ฐ€ ๋ด…๋‹ˆ๋‹ค
์ž๊ทน์œผ๋กœ ์ƒ๊ฐํ•˜๊ณ  ๋” ์—ด์‹ฌํžˆ ํ•ด๋ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค

์ €๋Š” 3๊ฐ€์ง€๋กœ ๋‚˜๋ˆ ์„œ ํ’€์—ˆ์Šต๋‹ˆ๋‹ค

  1. A๊ฐ€ ๊ณ ๋ฅผ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์กฐํ•ฉ์„ DFS๋กœ ์ƒ์„ฑํ•˜๊ณ 
  2. ๊ฐ ์กฐํ•ฉ๋งˆ๋‹ค A/B์˜ ๋ชจ๋“  ํ•ฉ์„ ๋งŒ๋“ค์–ด์„œ, B ํ•ฉ์„ ์ •๋ ฌํ•œ ๋’ค A ํ•ฉ๋งˆ๋‹ค lower_bound๋กœ B < A์ธ ๊ฐœ์ˆ˜๋งŒํผ ์Šน์ˆ˜๋ฅผ ํ•ฉ์‚ฐํ•œ ๋’ค
  3. ์Šน์ˆ˜๊ฐ€ ์ตœ๋Œ€์ธ ์กฐํ•ฉ์„ ์ฑ„ํƒํ•˜๊ณ , ๋™๋ฅ ์ด๋ฉด ์‚ฌ์ „์ˆœ์œผ๋กœ ๊ฐ€์žฅ ๋น ๋ฅธ ์กฐํ•ฉ์„ ํƒํ–ˆ๋„ค์š”

์ œ ์ฝ”๋“œ ๋„ˆ๋ฌด ๋ณต์žกํ•˜๊ณ  ๋ฉ”์†Œ๋“œ๋„ ๋งŽ์•„์„œ ๊ทธ๋ƒฅ ํ๋ฆ„๋งŒ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค

์ข‹์€ ๋ฌธ์ œ ๊ฐ€์ ธ์™€์ฃผ์…”์„œ ๊ฐ์‚ฌํ•˜๊ณ  ๋ฌธ์ œํ‘ธ๋А๋ผ ๊ณ ์ƒํ•˜์…จ์Šต๋‹ˆ๋‹ค!

์ฃผ์‚ฌ์œ„ ๊ณ ๋ฅด๊ธฐ
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

static void buildSums(const vector<vector<int>>& dice, const vector<int>& idxs, vector<int>& out) {
    out.clear();
    out.push_back(0);
    for (size_t t = 0; t < idxs.size(); t++) {
        vector<int> next;
        next.reserve(out.size() * 6);
        const vector<int>& d = dice[idxs[t]];
        for (size_t i = 0; i < out.size(); i++) {
            for (size_t f = 0; f < d.size(); f++) {
                next.push_back(out[i] + d[f]);
            }
        }
        out.swap(next);
    }
}

static bool lexSmaller(const vector<int>& a, const vector<int>& b) {
    size_t n = a.size();
    for (size_t i = 0; i < n; i++) {
        if (a[i] != b[i]) {
            return a[i] < b[i];
        }
    }
    return false;
}

static void complementIndices(int n, const vector<int>& pick, vector<int>& rest) {
    rest.clear();
    vector<char> used(n, 0);
    for (size_t i = 0; i < pick.size(); i++) {
        used[pick[i]] = 1;
    }
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            rest.push_back(i);
        }
    }
}

vector<int> solution(vector<vector<int>> dice) {
    int n = static_cast<int>(dice.size());
    int half = n / 2;

    vector<int> bestChoice;
    long long bestWin = -1;

    vector<int> comb;
    comb.reserve(half);

    vector<int> aIdx, bIdx;
    vector<int> aSums, bSums;

    function<void(int,int)> dfs = [&](int start, int need) {
        if (need == 0) {
            aIdx = comb;
            complementIndices(n, aIdx, bIdx);

            buildSums(dice, aIdx, aSums);
            buildSums(dice, bIdx, bSums);

            sort(bSums.begin(), bSums.end());

            long long win = 0;
            for (size_t i = 0; i < aSums.size(); i++) {
                int x = aSums[i];
                auto it = lower_bound(bSums.begin(), bSums.end(), x);
                win += static_cast<long long>(it - bSums.begin());
            }

            if (win > bestWin) {
                bestWin = win;
                bestChoice = aIdx;
            } else if (win == bestWin) {
                if (lexSmaller(aIdx, bestChoice)) {
                    bestChoice = aIdx;
                }
            }
            return;
        }

        for (int i = start; i <= n - need; i++) {
            comb.push_back(i);
            dfs(i + 1, need - 1);
            comb.pop_back();
        }
    };

    dfs(0, half);

    vector<int> answer;
    answer.reserve(half);
    for (size_t i = 0; i < bestChoice.size(); i++) {
        answer.push_back(bestChoice[i] + 1);
    }
    return answer;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants