11052번: 카드 구매하기
첫째 줄에 민규가 구매하려고 하는 카드의 개수 N이 주어진다. (1 ≤ N ≤ 1,000) 둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 ≤ Pi ≤ 10,000)
www.acmicpc.net
간단한 dp문제였다.
Top-down 방식으로 푸는 경우, N개의 카드를 가장 비싸게 구입하는 금액은 카드를 i개 묶음을 구입하는 금액 + N-i개의 카드를 가장 비싸게 구입하는 금액이다. 여기서 i를 1~N까지 반복하여 그 중 최대값을 구해주면 된다.
따라서 점화식은 다음과 같다.
for(i=1; i<=N; i++)
dp(N) = max(dp[N], dp[N-i] + P[i]);
Bottom-up 방식으로 푸는 경우, 이중 for문을 통해 구현할 수 있으며 점화식은 Top-down 방식과 동일하다.
#include <iostream>
using namespace std;
int P[1001], memo[1001];
inline int max(int a, int b) { return a > b ? a : b; }
int Topdown(int N)
{
if (N == 0) return 0;
int& ret = memo[N];
if (ret != 0) return ret;
for (int i = 1; i <= N; i++)
ret = max(ret, Topdown(N - i) + P[i]);
return ret;
}
int Bottomup(int N)
{
// memo[0] = 0 으로 초기화 해줘야 하지만 전역변수는 기본값이 0이므로 생략
for (int i = 1; i <= N; i++)
for (int j = 1; j <= i; j++)
memo[i] = max(memo[i], memo[i - j] + P[j]);
return memo[N];
}
int main(void)
{
int N;
cin >> N;
for (int i = 1; i <= N; i++)
cin >> P[i];
// top-down
cout << "Top-down: " << Topdown(N) << endl;
// Bottom-up
cout << "Bottom-up: "<< Bottomup(N) << endl;
return 0;
}
알고리즘 200일 프로젝트 - 70 day
'알고리즘 > BOJ' 카테고리의 다른 글
백준 9465번: 스티커 (0) | 2020.06.16 |
---|---|
백준 2163번: 초콜릿 자르기 (0) | 2020.06.15 |
백준 14501번: 퇴사 (dp) (0) | 2020.06.12 |
백준 9461번: 파도반 수열 (0) | 2020.06.10 |
백준 11727번: 2 x n 타일링 2 (0) | 2020.06.10 |