ABC119 C - Synthetic Kadomatsu
備忘録
問題
回答
import sys import os import math import bisect import itertools import collections import heapq import queue import array # 時々使う # from scipy.sparse.csgraph import csgraph_from_dense, floyd_warshall # from decimal import Decimal # from collections import defaultdict, deque # 再帰の制限設定 sys.setrecursionlimit(10000000) def ii(): return int(sys.stdin.buffer.readline().rstrip()) def il(): return list(map(int, sys.stdin.buffer.readline().split())) def fl(): return list(map(float, sys.stdin.buffer.readline().split())) def iln(n): return [int(sys.stdin.buffer.readline().rstrip()) for _ in range(n)] def iss(): return sys.stdin.buffer.readline().decode().rstrip() def sl(): return list(map(str, sys.stdin.buffer.readline().decode().split())) def isn(n): return [sys.stdin.buffer.readline().decode().rstrip() for _ in range(n)] def lcm(x, y): return (x * y) // math.gcd(x, y) MOD = 10 ** 9 + 7 INF = float('inf') def dfs(N, current, A, a, B, b, C, c, L): if N == current: if a == 0 or b == 0 or c == 0: # 竹を1つも使用していない場合 return INF return abs(A-a) + abs(B-b) + abs(C-c) # 竹を使用しない場合 w = dfs(N, current+1, A, a, B, b, C, c, L) # 竹を各A, B, Cのどれかに使用する場合 # ただし、合成魔法を使用しない場合(加算する竹a,b,cが0のとき)には+10しない x = dfs(N, current+1, A, a+L[current], B, b, C, c, L) + 10*(a != 0) y = dfs(N, current+1, A, a, B, b+L[current], C, c, L) + 10*(b != 0) z = dfs(N, current+1, A, a, B, b, C, c+L[current], L) + 10*(c != 0) return min(w, x, y, z) def main(): if os.getenv("LOCAL"): sys.stdin = open("input.txt", "r") N, A, B, C = il() L = [ii() for _ in range(N)] print(dfs(N, 0, A, 0, B, 0, C, 0, L)) if __name__ == '__main__': main()
考え方
全探索で回答を求める問題です。
各竹に対して、取りうる選択を全て試して、最小のMPを求めます。
- 回答概要
- 足し算と引き算は計算の順番が変化しても答えが一意になるため、使用する竹の順番は考慮しない
- ケース数が少ないため、発生しうるケースを全探索する
まず、竹の使用順と各魔法について考えます。
延長魔法で必要なMPは目的の竹の長さ - 今の竹の長さ
で求めることが出来ます。
また、短縮魔法についても同様です。
そのため、延長魔法と短縮魔法は目的の竹の長さ
と今の竹の長さ
の差の絶対値を取ればよいことがわかります。
各魔法を使用した際の消費MPは全て加算によって計算されます。
したがって、魔法を使用する順を変えても、最終的に必要なMPは変化しません。
(魔法を使用する順番を考慮する必要はない)
次に、各N(3 <= N <= 8)
本の竹が取りうる選択について考えます。
竹を使用するときの選択肢は、
「使用しない」「竹Aを作るために使用する」
「竹Bを作るために使用する」「竹Cを作るために使用する」
の4通りです。
したがって、全てのケースを試しても4 ^ 8 = 65536
通りなので全探索で回答を求めます。