본문 바로가기

백준/DP

[KOI] 백준 1866 - 택배

728x90

www.acmicpc.net/problem/1866

사전 지식

이 문제를 풀기 전에 USACO wifi setupBOJ 14400을 풀고 오는 것을 추천한다.

 

솔루션 - 편의점 2 / 솔루션 - wifi setup

풀이

트럭과 헬기를 적절히 써서 비용의 합을 최소로 해야한다.

 

비용의 최소는 wifi setup과 비슷하게 일차원 동적계획법으로 계산할 수 있다.

 

테이블의 정의는 dp[i] := i번째 지점까지 배송했을 때 비용의 최소

 

로 할 수 있으며 i번째 지점을 트럭으로 배송하거나 헬기로 어떤 지점에 물건을 나르고 그 지점에서 i번째 지점으로 트럭이 오는 경우로 나눠 계산하게 된다.

 

헬기로 배송한다고 했을 때 가장 이득을 보는 위치는 어떤 구간을 배송하기 위해 헬기를 이용할 때 그 구간의 중간 지점이 된다.

 

그렇게 해야 헬기로 배송한 지점에서 다른 지점으로 배달하려는 거리의 합이 최소가 되기 때문이다. (편의점 2 참조)

 

이렇게 구간의 중간 지점을 구해야 하므로 주어진 지점 정보들은 거리순으로 정렬되어야만 한다.

 

최적해 계산은 이중 반복문을 통해 이루어진다.(i번째 지점까지 배송하면서 헬기를 j ~ i 구간 배송에 이용할 때)

 

헬기를 이용할 때 비용은 누적 합으로 미리 저장하여 계산을 빠르게 할 수 있다.

 

누적 합 테이블은 다음과 같이 정의한다.

 

prefix[i][j] := i번째 지점에서 j번째 지점까지 배송하는데 드는 비용

 

누적합을 구하고 dp[i] = min(dp[i - 1] + ar[i] * truck_cost, dp[j - 1] + heli_cost + preifx[middle][i] + prefix[middle][j]) 이 계산을 통해 모든 지점에 배송하는 최소 비용을 구할 수 있다.

 

전체 코드

더보기
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
32
33
34
35
36
37
38
39
40
41
42
#include <bits/stdc++.h>
     
using namespace std;
 
int stuff[3001];
int n;
int drive, heli;
int dp[3001];
int prefix[3001][3001];
 
inline int getm(int a, int b) { return (a + b) / 2; }
 
int main()
{
    fill(dp + 1, dp + 30011e9 + 1);
    cin.tie(0); ios::sync_with_stdio(false);
    cin >> n;
 
    for (int i = 1; i <= n; ++i)
        cin >> stuff[i];
    cin >> drive >> heli;
    sort(stuff + 1, stuff + 1 + n);
    
    for (int i = 1; i <= n; ++i)
    {
        int crd = stuff[i];
        for (int j = i - 1; j >= 1--j)
            prefix[i][j] = prefix[i][j + 1+ abs(crd - stuff[j]) * drive;
        for (int k = i + 1; k <= n; ++k)
            prefix[i][k] = prefix[i][k - 1+ abs(stuff[k] - crd) * drive;
    }
    
    for (int i = 1; i <= n; ++i)
    {
        dp[i] = drive * stuff[i] + dp[i - 1];
 
        for (int j = i; j > 0--j)
            dp[i] = min(dp[i], dp[j - 1+ heli + prefix[getm(i, j)][i] + prefix[getm(i, j)][j]);
    }
 
    cout << dp[n];
}
cs
728x90

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

백준 1311 - 할 일 정하기 1  (0) 2021.02.09
[USACO] 백준 14165 - Team Building  (0) 2021.01.31
백준 15678 - 연세워터파크  (0) 2021.01.26
[KOI] 백준 2494 - 숫자 맞추기  (0) 2021.01.24
백준 1514 - 자물쇠  (0) 2021.01.18