๊ธ€ ์ž‘์„ฑ์ž: ์ด์ง€์›๐ŸŒฉ๏ธ

์ •ํ™•ํžˆ ํ•œ ์‹œ๊ฐ„ ๊ฑธ๋ ค์„œ ํ’€์—ˆ๋‹ค. ์ •๋‹ต ์ฝ”๋“œ ํ•˜๋‹จ์— ์‹œ๊ฐ„ ์ดˆ๊ณผ, ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ ์ฝ”๋“œ๋„ ๊ฐ™์ด ์ฒจ๋ถ€ํ–ˆ๋‹ค.

  1. ์ผ๋‹จ, ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ๊ฐ€ ๋‚ฌ์„ ๋•Œ๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ 2์ฐจ์› ๋ฐฐ์—ด๋กœ ์ €์žฅํ•ด์„œ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ์˜€๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ๊ฐ€ ๋‚œ ํ›„์—, ๊ตณ์ด ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฑธ ๊นจ๋‹ฌ์•„์„œ ์ €์žฅํ•˜์ง€ ์•Š๊ณ , ๋ฐ”๋กœ ์ ์ˆ˜ ๊ณ„์‚ฐํ•˜๋Š” ์‹์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค.
  2. ๊ทธ๋ฆฌ๊ณ  ์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝํ•˜๋ฉด์„œ, ์งˆ๋ฌธ ๊ฒŒ์‹œํŒ์„ ๋ณด๋‹ˆ ์ „์ฒด ํŒ€์„ ์ง‘ํ•ฉ์œผ๋กœ ๋งŒ๋“ค์–ด ๋†“๊ณ , n / 2์˜ ์กฐํ•ฉ์„ ๊ตฌํ•œ ํ›„์—, ์ฐจ์ง‘ํ•ฉ์„ ๊ตฌํ•˜๋Š” ์‹์œผ๋กœ ๋งํฌ ํŒ€์„ ๊ตฌํ•˜๋ผ๋Š” ์ด์•ผ๊ธฐ๊ฐ€ ์žˆ์–ด์„œ ๊ทธ๊ฒƒ๋„ ๋ฐ˜์˜ํ–ˆ๋‹ค. ์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ์‹œ๊ฐ„ ์ดˆ๊ณผ ๋‚œ ์ฝ”๋“œ์˜€๋‹ค.
  3. ๋„๋ฌด์ง€ ํ•ด๊ฒฐ์ฑ…์„ ๋ชจ๋ฅด๊ฒ ์–ด์„œ, PyPy3๋กœ๋„ ์‹คํ–‰ํ•ด๋ดค๋Š”๋ฐ ์—ญ์‹œ๋‚˜ ์‹œ๊ฐ„์ดˆ๊ณผ์˜€๋‹ค. ๋‹ค๋ฅธ ๊ธ€์„ ์ฐพ์•„๋ณด๋‹ˆ ๋Œ€๊ฒŒ, ์‹œ๊ฐ„ ์ดˆ๊ณผ ๋‚œ ์ฝ”๋“œ๋“ค์€ ์กฐํ•ฉ ๊ตฌํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋น„ํšจ์œจ์ ์ด๋ผ๋Š” ๋‹ต๋ณ€์„ ๋ดค๋‹ค. ๊ทธ๋ž˜์„œ ์–ธ์  ๊ฐ€ ์ €์žฅํ•ด๋†จ๋˜, ๋‹ค๋ฅธ ๋ถ„์˜ ์กฐํ•ฉ ์ฝ”๋“œ๋ฅผ ์กฐ๊ธˆ ์ˆ˜์ •ํ•ด์„œ ์‹คํ–‰ํ–ˆ๋”๋‹ˆ ํ†ต๊ณผํ–ˆ๋‹ค. ํ•œ๋งˆ๋””๋กœ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์ฝ”๋“œ๊ฐ€ ๋Š๋ฆฌ๋‹ค๋Š” ๊ฒƒ... ์œผ์•„์•„์•„!
  4. ์•„๋ฌดํŠผ ๊ฒฐ๊ตญ ํ’€์—ˆ๊ณ ... ์•ž์œผ๋กœ๋Š” ์ด๋ฒˆ์— ์‚ฌ์šฉํ•œ ์กฐํ•ฉ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฑธ๋กœ... ํ˜ผ์ž ํ•ฉ์˜ ๋ดค๋‹ค. ์ด๊ฒƒ๋„ ์™ธ์šธ ์ˆ˜ ์žˆ์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต์ ์œผ๋กœ ์—ฐ์Šตํ•ด์„œ ์ž‘์„ฑํ•ด๋ด์•ผ์ง€.

 

๋ฌธ์ œ

https://www.acmicpc.net/problem/14889

 

๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ

Swift: ์ •๋‹ต

let n = Int(readLine()!)!
let m = Int(n/2)
var score = [[Int]]()
var totalTeam = Set(Array(0..<n))
for _ in 0..<n {
    let line = readLine()!.split(separator: " ").map { Int(String($0))! }
    score.append(line)
}

var answer = 987654321

func cal(startTeam: [Int], linkTeam: [Int]) {
    var startTeamSum = 0
    var linkTeamSum = 0
    for i in 0..<m {
        for j in i+1..<m {
            startTeamSum += score[startTeam[i]][startTeam[j]] + score[startTeam[j]][startTeam[i]]
            linkTeamSum += score[linkTeam[i]][linkTeam[j]] + score[linkTeam[j]][linkTeam[i]]
        }
    }

    answer = min(answer, abs(startTeamSum - linkTeamSum))
}

func combination(of total: [Int], selectedCount: Int, current idx: Int, seletcted: [Int]) {
    if selectedCount == 0 {
        cal(startTeam: seletcted, linkTeam: Array(totalTeam.subtracting(Set(seletcted))))
    } else if idx == total.count {
        return
    } else {
        let new = seletcted + [total[idx]]
        combination(of: total, selectedCount: selectedCount-1, current: idx+1, seletcted: new)
        combination(of: total, selectedCount: selectedCount, current: idx+1, seletcted: seletcted)
    }
}

combination(of: Array(0..<n), selectedCount: m, current: 0, seletcted: [])

print(answer)

 

Swift: ์‹œ๊ฐ„ ์ดˆ๊ณผ

let n = Int(readLine()!)!
let m = Int(n/2)
var score = [[Int]]()
var totalTeam = Set(Array(0..<n))
for _ in 0..<n {
    let line = readLine()!.split(separator: " ").map { Int(String($0))! }
    score.append(line)
}

var answer = 987654321

func cal(startTeam: [Int], linkTeam: [Int]) {
    var startTeamSum = 0
    var linkTeamSum = 0
    for i in 0..<m {
        for j in i+1..<m {
            startTeamSum += score[startTeam[i]][startTeam[j]] + score[startTeam[j]][startTeam[i]]
            linkTeamSum += score[linkTeam[i]][linkTeam[j]] + score[linkTeam[j]][linkTeam[i]]
        }
    }

    answer = min(answer, abs(startTeamSum - linkTeamSum))
}

var picked = [Int]()
var visited = Array(repeating: false, count: n)

func pick(toPick: Int) {
    if toPick == 0 {
        cal(startTeam: picked, linkTeam: totalTeam.subtracting(Set(picked)).sorted())
        return
    }
    for i in 0..<n {
        if visited[i] {
            continue
        }
        visited[i] = true
        picked.append(i)
        pick(toPick: toPick - 1)
        picked.removeLast()
        visited[i] = false
    }
}

pick(toPick: m)

print(answer)

 

Swift: ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ

let n = Int(readLine()!)!
var score = [[Int]]()

for _ in 0..<n {
    let line = readLine()!.split(separator: " ").map { Int(String($0))! }
    score.append(line)
}

var teams = [[Int]]()
var picked = [Int]()
var visited = Array(repeating: false, count: n)
func pick() {
    if picked.count == n {
        teams.append(picked)
        return
    }
    for i in 0..<n {
        if visited[i] {
            continue
        }
        visited[i] = true
        picked.append(i)
        pick()
        picked.removeLast()
        visited[i] = false
    }
}

pick()

var answer = 987654321
for team in teams {
    var startTeam = 0
    for i in 0..<n/2 {
        for j in i+1..<n/2 {
            startTeam += score[team[i]][team[j]]
            startTeam += score[team[j]][team[i]]
        }
    }
    var linkTeam = 0
    for i in n/2..<n {
        for j in i+1..<n {
            linkTeam += score[team[i]][team[j]]
            linkTeam += score[team[j]][team[i]]
        }
    }
    answer = min(answer, abs(startTeam - linkTeam))
}

print(answer)
๋ฐ˜์‘ํ˜•