본문 바로가기
알고리즘/백준

[BAEKJOON]24267 카드 구매하기 2

by 응애~ 개발자 2023. 2. 23.
728x90
반응형

문제 요약

  • 알고리즘 분류: 동적계획법, dp
  • 난이도: Silver1
  • 문제내용:
    • N개가 주어지고 1 부터 N까지의 팩의 개수와 가격이 있다.
    • i번째는 팩개수를 나타내고 팩 개수마다 가격이 붙어 있다.
    • N개 카드를 구입할때 가장 싸게 구입할수있는 가격을 출력해라.
 

16194번: 카드 구매하기 2

첫째 줄에 민규가 구매하려고 하는 카드의 개수 N이 주어진다. (1 ≤ N ≤ 1,000) 둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 ≤ Pi ≤ 10,000)

www.acmicpc.net

문제풀이

 이번 문제에는 모든 경우의 수를 구해서 풀기가 힘들다. 모든 경우의 수로 풀라면 재귀호출방식으로 해야 하는데 재귀호출시 시간초과가 나오므로 dp로 풀여야 될 문제이다. dp에 관련된 설명은 여기에서 확인해보면된다.  그리고 아래 사이트문제에서 max → min으로만 바꾸면 되기 때문에 아래사이트 문제를 참고 하고 문제 풀이를 보는것을 추천한다.

https://jih3508.tistory.com/137

 

[BAEKJOON]11052 카드 구매하기

문제 요약 알고리즘 분류: 동적계획법, dp 난이도: Silver1 문제내용: N개가 주어지고 1 부터 N까지의 팩의 개수와 가격이 있다. i번째는 팩개수를 나타내고 팩 개수마다 가격이 붙어 있다. N개 카드

jih3508.tistory.com

문제 접근방법

 dp는 구현보다 아이디어를 요구하는 문제로서 생각만 한다면 코드 구현은 간단한다. 데이터가 최대 1000개이고 파이썬이 초당 2천만번 연산이 가능하다고 가정할때 O(N ^ 2)까지는 가능하다고 보면된다. 그러면 이중 for문으로 처리가 가능하다.

 어떤식으로 이중 for문으로 점화식을 계산 할거라면 우선 N번째까지 반목문으로 작성한 다음 반복문안에서 또 i번째까지 반복문으로 해서 각 i번째 마다 최소값으로 나올수 있는 수를 저장할것이다. 즉 i 번째 까지 가장 작은 값이 나올수 있는 수는 i번째와 i 에서 i - j까지의 가장 큰값과  j번째 팩 가격을 더한 값중 작은 값은 i번째에 저장하는식으로 진행 하면된다. 점화식을 세우면 아래와 같다.

dp[i] = min(dp[i], dp[i - j] + pack[j])

dp는 i 번째 까지의 최대값 pack은 각 카드 가격이라고 보면된다. 아래 그림은 예제5를 표로 나타낸것이니 참고 해보면된다.

  • 0번째 인덱스는 첫번째라서 그래로 넣어 준다.(pack[0])
  • 1번째 인덱스는 0번째 인덱스 2번 더하는것 보다 1번째 인덱스 값이 작다.(pack[1])
  • 2번째 인덱스는 2번째 인덱스값이랑 1번째 인덱스 3번 더하는것과 0번째 + 1번째 더한것중 2번째 인덱스와 0번째 + 1번째 인덱스 더하는것값이 가장 작다.(pacl[2], pack[0] + pack[1])
  • 3번째는 1번째 인덱스 2번 더한것이 가장작다. (pack[1] + pack[1])

Code

Python

N = int(input())
p = list(map(int, input().split()))
dp = [0] * N
dp[0] = p[0]

for i in range(1, N):
    dp[i] = p[i]
    for j in range(i):
        dp[i] = min(dp[i], dp[j] + p[i -j - 1])

print(dp[-1])

Java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int N = Integer.parseInt(br.readLine());
		StringTokenizer st = new StringTokenizer(br.readLine());
		int[] p = new int[N];
		int[] dp = new int[N];
		for(int i = 0; i < N; i++) {
			p[i] = Integer.parseInt(st.nextToken());
		}
		dp[0] = p[0];
		for(int i = 1; i < N; i++) {
			dp[i] = p[i];
			for(int j = 0; j < i; j++) {
				dp[i] = Math.min(dp[i], dp[j] + p[i - j - 1]);
			}
		}
		System.out.println(dp[N - 1]);		
	}

}

 

728x90
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[BAEKJOON]1926 그림  (2) 2023.03.06
[BAEKJOON]2529 부등호  (0) 2023.03.03
[BAEKJOON]1759 암호 만들기 - python  (0) 2023.02.22
[BAEKJOON]1890 점프  (0) 2023.02.21
[BAEKJOON]1987 알파벳- Python  (0) 2023.02.20