문제


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


풀이


조금 이색적인 문제였다.

DAG에서 순회하면서 노드 가중치 합의 최대를 구하는데, 꼭 더해야 하는 것은 아니며 대신 더할 때마다 1 / 2 ** k의 가중치가 추가로 곱해진다.

지금까지 선택한 노드의 개수와 현재 위치가 주어지면 부분 문제가 결정되므로 N * N DP 테이블을 만들어 풀려고 했으나 n이 최대 5 * 10 ** 5라서 바로 MLE가 나온다.

무한등비급수에서 아이디어를 얻어보면, 현재 위치만 주어져도 문제를 해결할 수 있다.

# i번째 노드를 선택할 때
res = max(res, enjoy[i] / 2 ** k + f(j, k + 1))

# i번째 노드를 건너뛸 때
res = max(res, f(j, k))

이런 식으로 현재 노드에 1 / 2 ** k 가중치를 곱해주는 게 아닌,

# i번째 노드를 선택할 때
res = max(res, enjoy[i] + f(j) / 2)

# i번째 노드를 건너뛸 때
res = max(res, f(j))

앞으로 얻을 합을 2로만 나눠주면 된다.


> 코드


import sys
sys.setrecursionlimit(5 * 10 ** 5)

n, m = map(int, sys.stdin.readline().split())
enjoy = list(map(int, sys.stdin.readline().split()))
graph = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, sys.stdin.readline().split())
    graph[a].append(b)

dp = [-1] * n


def f(i):
    if dp[i] != -1:
        return dp[i]
    
    res = enjoy[i]
    for j in graph[i]:
        res = max(res, enjoy[i] + f(j) / 2)
        res = max(res, f(j))
    
    dp[i] = res
    return res


print(f(0))

Leave a comment