문제 링크
문제 요약
주어진 여러 금융 상품들로 구성된 포트폴리오의 현재 가치를 계산하는 문제입니다. 금융 상품은 크게 두 가지로 나뉩니다:
- 기본 투자 (Basic Investments): 직접적인 현재 가치가 주어집니다.
- 파생 상품 (Derivatives): 다른 기본 투자나 더 낮은 번호의 파생 상품들로 구성되며, 각 구성 요소의 기여율이 주어집니다. 파생 상품은 항상 낮은 번호의 상품들로만 구성되므로 순환 의존성이 없습니다.
우리는 초기 B
개의 기본 투자의 현재 가치를 알고, 이후 D
개의 파생 상품들의 구성 정보를 알게 됩니다. 마지막으로, 전체 포트폴리오가 각 기본 투자와 파생 상품에 대해 어느 비율로 구성되어 있는지 주어집니다. 이 정보를 바탕으로 포트폴리오의 총 현재 가치를 계산하고 소수점 둘째 자리까지 출력해야 합니다.
풀이
문제의 핵심은 파생 상품의 가치를 계산하는 순서입니다. 각 파생 상품은 항상 자신보다 낮은 번호의 투자 상품(기본 투자 또는 이미 계산된 파생 상품)으로 구성된다는 조건이 있습니다. 이는 의존성 관계가 단방향이라는 것을 의미하며, 따라서 파생 상품의 번호 순서대로 가치를 계산해 나갈 수 있습니다.
- 기본 투자 가치 초기화: 먼저 주어진
B
개의 기본 투자의 현재 가치를 리스트(prices)에 저장합니다. - 파생 상품 가치 계산:
D
개의 파생 상품에 대해 순서대로 가치를 계산합니다.- 각 파생 상품(
B+d
번째)은 자신보다 낮은 번호의 상품들(1
부터B+d-1
까지)로 구성됩니다. 이 시점에서prices
리스트에는 이미 해당 구성 상품들의 가치가 모두 저장되어 있습니다. - 주어진 각 구성 상품의 기여율을 해당 상품의 현재 가치에 곱한 후 모두 더하여 현재 파생 상품의 가치를 계산합니다.
- 계산된 파생 상품의 가치를
prices
리스트에 추가합니다. 이 과정을D
번 반복하면prices
리스트에는 모든B
개의 기본 투자와D
개의 파생 상품의 현재 가치가 순서대로 저장됩니다.
- 각 파생 상품(
- 포트폴리오 총 가치 계산: 마지막으로, 전체 포트폴리오가 각 상품(기본 투자 및 파생 상품)에 대해 어느 비율로 구성되어 있는지 주어집니다.
B+D
개의 각 상품에 대한 포트폴리오 기여율(investment_rates
)을 읽어옵니다.- 각 상품의 기여율을 해당 상품의
prices
리스트에 저장된 현재 가치에 곱한 후 모두 더합니다. 이 합계가 포트폴리오의 최종 현재 가치입니다.
- 결과 출력: 계산된 포트폴리오의 총 가치를 소수점 둘째 자리까지 반올림하여 출력합니다.
정답 코드
def solve():
B, D = map(int, input().split())
prices = [*map(float, input().split())] # B개의 기본 투자의 현재 가치를 저장
derivatives = [[*map(float, input().split())] for _ in range(D)] # D개의 파생 상품 구성 정보를 저장
investment_rates = [*map(float, input().split())] # B+D개의 포트폴리오 투자 비율을 저장
# 파생 상품의 가치를 순서대로 계산하여 prices 리스트에 추가
# derivatives[i]는 i+1번째 파생 상품(B+1, B+2, ...)에 대한 구성 정보를 담고 있다.
# 각 derivative[i]는 B+i개의 요소를 가지며, 이는 1 ~ (B+i)번까지의 상품들로 구성된다는 의미.
for derivative_composition in derivatives:
# 현재 파생 상품의 가치는 그를 구성하는 하위 상품들의 가치 * 기여율의 합
current_derivative_value = sum([rate * prices[j] for j, rate in enumerate(derivative_composition)])
prices.append(current_derivative_value) # 계산된 파생 상품 가치를 prices 리스트에 추가
# 전체 포트폴리오의 총 가치 계산
# investment_rates[i] * prices[i]를 모두 더한다.
total_portfolio_value = sum([investment_rates[i] * prices[i] for i in range(B + D)])
return total_portfolio_value
if __name__ == "__main__":
tc = ii() # 테스트 케이스 수
for t in range(1, tc+1):
ret = solve() # 각 테스트 케이스에 대한 결과 계산
print(f"Data Set {t}:\n{ret:.2f}\n") # 형식에 맞춰 출력 (소수점 둘째 자리까지)