Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 반효경
- concurrency control
- 시그널 핸들러
- 네트워크
- 백엔드
- 개발남노씨
- 코딩테스트 [ ALL IN ONE ]
- vite
- SDK
- recoverability
- CPU 스케줄링
- SQL
- 쉬운코드
- 온디바이스AI
- 운영체제와 정보기술의 원리
- Git
- 커널 동기화
- 인터럽트
- 쉬운 코드
- 갤럭시 S24
- 운영체제
- Extendable hashing
- 프로세스 주소 공간
- 코딩애플
- 데이터베이스
- 김영한
- 시스템프로그래밍
- B tree 데이터삽입
- BreadcrumbsComputer-Networking_A-Top-Down-Approach
- 트랜잭션
Archives
- Today
- Total
티끌모아 태산
11052: 카드 구매하기 본문
728x90
https://www.acmicpc.net/problem/11052
11052번: 카드 구매하기
첫째 줄에 민규가 구매하려고 하는 카드의 개수 N이 주어진다. (1 ≤ N ≤ 1,000) 둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 ≤ Pi ≤ 10,000)
www.acmicpc.net
설명
카드 팩의 가격이 주어졌을 때, N개의 카드를 구매하기 위해 민규가 지불해야 하는 금액의 최댓값을 구하는 프로그램 작성. 이때, N개보다 많은 개수의 카드를 산 다음, 나머지 카드를 버려서 N개를 만드는 것을 불가능. 즉, 구매한 카드팩에 포함되어 있는 카드 개수의 합은 N과 같아야 한다.
- 카드는 카드팩의 형태로만 구매 가능.
- 각 카드에는 등급이 있고 8가지 등급으로 나뉘어짐.
- 카드팩의 종류는 카드 1개가 포함된 카드팩, 카드 2개가 포함된 카드팩, ... , 카드 N개가 포함 된 카드팩과 같이 총 N가지가 존재.
- 민규는 최대한 많은 돈을 지불해서 카드 N개를 구매하려고 한다. 카드 i개가 포함된 카드팩의 가격은 Pi원이다.
핵심 아이디어
- 다이나믹 프로그래밍
- 작은 문제부터 생각해보자! 카드를 한 개 구매하는 것 부터 시작. 1부터 n까지 각각의 카드 수를 위한 금액의 최댓값을 구해나가는 것.
- dp[i] = 카드 i개 구해하는 최대 가격, p[k] = k개가 들어있는 카드팩 가격
# 3 5 15 16을 예로 들자
# dp[i] = 카드 i개 구매 하는 최대 가격, p[k] = k개가 들어있는 카드팩 가격
dp[1] = 3 # dp[1] == p[1] -> dp[0] + p[1]
dp[2] = 8, max(dp[1] + p[1], p[2]) # 1나 짜리 2개 구매 or 2개짜리 하나 구매
# 하나 * 3 또는 하나 + 두 개 또는 세 개 * 1
dp[3] = 15, max(dp[2]+ p[1], dp[1] + p[2], p[3])
# 하나 * 4, 두 개 * 2, 하나 + 세 개, 네 개
dp[4] = 18, max(dp[3] + p[1], dp[2] + p[2], dp[1] + p[3], p[4])
이를 점화 식으로 풀어내면 다음과 같다. dp[i] 에 대해서 j는 1부터 i까지 증가하면서 dp[i] = dp[i-j] + p[j](j값에 따른 max값)
dp[i] = dp[i-k] + p[k] (k값에 따른 max값)
인덱스를 0부터 하면 헷가리는 감이 있어서 dp[0] 은 0으로 채우고 1부터 시작했다.
코드 구현
n = int(input())
p = [0] + list(map(int, input().split()))
dp = [0] * (n+1) # dp = [0] * 1001 가능
# 반복문을 통해 각 카드 개수의 지불하는 최대 금액 구하기
for i in range(1, n+1):
for k in range(1, i+1):
dp[i] = max(dp[i], dp[i-k] + p[k])
print(dp[n])
반복문을 통해 각 카드 개수의 지불하는 최대 금액을 구해 준다. 각 카드 개수의 지불하는 최대 금액과 이전의 카드를 지불한 최대 금액 + 현재 카드팩 가격을 비교한다.
728x90
'백준 문제 > DP' 카테고리의 다른 글
14501: 퇴사 (0) | 2024.03.11 |
---|---|
2156: 포도주 시식 (0) | 2024.03.10 |
1912: 연속합 (0) | 2024.03.10 |