https://www.acmicpc.net/problem/1106
적어도 c
명 영업 => c
명, c+1
명, ..., c+100
명
(입력: 1개 도시에서 x
원으로 영업하는 최대 고객 수 = 100
명)
적어도 c
명을 늘리기 위한 최소 금액
=> c
명, c+1
명, ..., c+100
명 늘리는 최소 금액에서 최소값
적어도 i
명(i <= 입력 c
)을 늘리기 위한 최소 금액
=> i
명, i+1
명, ..., c+100
명 늘리는 최소 금액에서 최소값
int[] dp
dp[i]
: 고객을 i
명 만큼 늘릴 때, 최소 비용
출력, 고객을 적어도 c
명 늘릴 때의 최소 비용
= dp[c]
~ dp[c + 100]
중, 최소값
고객을 적어도 c
명 늘릴 때의 최소 비용
= dp[c]
~ dp[c + 100]
중, 최소값
=> 각 도시에서 홍보할 때 늘리는 고객 수 customer
에 대해 (customer <= 입력 c
),
dp[customer] ~ dp[c + 100]
채워나감
고객을 i
명 만큼 늘릴 때의 최소 비용 = dp[i]
=> 이번 도시에서 홍보 O or X 2가지 경우
① 현재 도시에서 홍보 O하는 경우
dp[i] = dp[i - customer] + cost
(i - customer)
고객 수 만큼 늘렸을 때의 최소 비용 +② 현재 도시에서 홍보 X하는 경우
dp[i] = dp[i]
=> dp[i] = min( dp[i], dp[i - customer] + cost )
int[] dp
: DP 배열int
가능DP 배열 채우기: 대략 O(n x (c+100))
=> n 최대값 대입: 200 x 1,100 = 22 x 10^4
출력 최소값 찾기: O(100)
=> 총 시간 복잡도: 대략 22 x 10^4 << 2억
import java.io.*;
import java.util.*;
public class Main {
static int c, n; // 최소 영업 고객 수 c, 도시 개수 n
static int[] dp; // dp[i]: 고객 i명 만큼 늘릴 때, 최소 비용
static int minCost = Integer.MAX_VALUE; // 출력, 최소 비용
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in)
);
StringTokenizer st = new StringTokenizer(br.readLine());
c = Integer.parseInt(st.nextToken());
n = Integer.parseInt(st.nextToken());
dp = new int[c + 101];
Arrays.fill(dp, (c + 100) * 100); // 비용 최대값
dp[0] = 0; // 초기식: 고객 0명 늘릴 때의 최소 비용 = 0원
for (int city = 0; city < n; city++) {
// 각 도시에서 홍보 비용 cost, 늘어나는 고객 수 customer
st = new StringTokenizer(br.readLine());
int cost = Integer.parseInt(st.nextToken());
int customer = Integer.parseInt(st.nextToken());
for (int i = customer; i <= c + 100; i++)
dp[i] = Math.min(dp[i], dp[i - customer] + cost);
}
// minCost 찾기 => dp[c] ~ dp[c + 100] 중, 최소값
for (int i = c; i <= c + 100; i++)
minCost = Math.min(minCost, dp[i]);
System.out.println(minCost);
}
}