G - Goin' to the Zoo 解説
by
cirno3153
実装例
各要素について \(0, 1, 2\) という多値を取る時は、再帰で実装すると楽に書けます。
計算量は \(O(3^NM)\) です。
import java.util.Scanner
import kotlin.math.min
import kotlin.Int
fun main() {
Scanner(System.`in`).use { sc ->
val N = sc.nextInt()
val M = sc.nextInt()
val C = IntArray(N) { sc.nextInt() }
val zoo = Array(N) {MutableList<Int>(0){0}} // 各動物園が持つ動物のリスト
for (i in 0 until M) {
var A = IntArray(sc.nextInt()) {sc.nextInt()}
for (j in A) zoo[j - 1].add(i)
}
var watched = IntArray(M) { 0 } // 各動物を見た回数
println(dfs(0, watched, C, zoo, 0))
}
}
fun dfs(i: Int, watched: IntArray, C: IntArray, zoo: Array<MutableList<Int>>, ans: Long): Long {
if (i == C.size) { // 再帰の終了条件
for (j in watched) {
if (j < 2) return Long.MAX_VALUE // ある動物について一度以下しか見ていない時は、適当に答えになり得ない値を返す
}
return ans
}
var ret = dfs(i + 1, watched, C, zoo, ans) // i番目の動物園を訪れない
for (j in zoo[i]) watched[j]++
ret = min(ret, dfs(i + 1, watched, C, zoo, ans + C[i])) // i番目の動物園を一度訪れる
for (j in zoo[i]) watched[j]++
ret = min(ret, dfs(i + 1, watched, C, zoo, ans + C[i] * 2)) // i番目の動物園を二度訪れる
for (j in zoo[i]) watched[j] -= 2
return ret
}
投稿日時:
最終更新:
