# ABC188 E - Peddler
ABC188 E - Peddler
問題へのリンク
問題概要
各街の金の値段は
制約
ABC中の解答
残り時間30分ほどしかなかったため途中でタイムアップ。コーディングしていたけどその後すぐ上書きで復習したためコードも残ってない。
辺の情報を片方の街にしか持たせない要因して、各街からの深さ優先探索でまずはやってみようとしていたと思う。
公式解法1
DAG (Directed Acyclic Graph, 閉路を含まない有向グラフ)の場合は以下のようなDPを考えればよいとそうだ。 (DPは苦手なので早く慣れたい)
配るDP :
DPの初期値には
こうすることで 各
他の街から移動してこれない街があるケースもあるが初期値に
from collections import defaultdict
import numpy as np
N, M = map(int, input().split())
A = np.array(list(map(int, input().split())))
G = defaultdict(list)
for _ in range(M):
x, y = map(int, input().split())
x, y = x - 1, y - 1
G[x].append(y)
# dp[i] : 街iに到達できる街 (街i自身を含まない) における金の最安値
# 配るDP : dp[j] <- min(dp[j], dp[i], Ai)
MAX = 10**10
dp = np.array([MAX] * N)
for at in range(N):
for to in G[at]:
dp[to] = min(dp[to], dp[at], A[at])
ans = (A - dp).max()
print(ans)
公式解法2
金の取引価格が一番低い街
-
からたどり着ける街x_1 をすべて列挙し、y で買いx_1 で売った場合の利益を記録するy -
を記録しこの後の作業ではたどり着ける街の候補から外すy -
と順番に同様の作業を繰り返すx_2, x_3, \dots
作業終了時の一番高い利益が答え。
答えはマイナスになることもあるので初期値に
苦肉の策としてはじめに見つけた値を入れるようにした。どうすればよりよいかまた調べておきたい。
from collections import defaultdict
import numpy as np
N, M = map(int, input().split())
A = np.array(list(map(int, input().split())))
G = defaultdict(list)
for _ in range(M):
x, y = map(int, input().split())
x, y = x - 1, y - 1
G[x].append(y)
ranks = np.argsort(A)
seen = np.zeros((N), dtype='bool')
rank = ranks[0]
seen[rank] = True
ans = 0 # -10**10
for key, value in G.items():
if value:
ans = A[value[0]] - A[key]
break
for rank in ranks:
seen[rank] = True
q = [rank]
V = []
while q:
at = q.pop()
for to in G[at]:
if seen[to]:
continue
seen[to] = True
q.append(to)
V.append(A[to])
if V:
ans = max(ans, max(V) - A[rank])
print(ans)
Discussion