코딩/백준 문제 풀이

BOJ 4243 - 보안 업체

stonejjun 2019. 12. 3. 14:11

문제 태그 : https://www.acmicpc.net/problem/4243

문제 설명

문제 풀이 (사고의 흐름)

일단 DP라는 것을 어느정도 바로 생각할 수 있었다. 직선에서 하는 DP인데 N이 작기 때문에 N^2이라고 생각을 했고, 이러면 보통 DP[i][j]는 i에서 j까지 ~~~ 라고 생각했다. 여기서 우리는 i 부터 j까지 다 들렀다면 당연히 최종위치는 i또는 j라는 것을 알 수 있다. 들르는데 걸리는 시간은 0이기 때문에 중간에 띄고 건널 이유가 아예없다. 그래서 관찰한 사실을 토대로 DP[state][i][j]는 state의 방향에 있으면서 i부터 j까지 들리는데 기다림의 합의 최소라고 생각할 수 있다.

하지만 이러면 문제가 있다. 지금까지 대기시간의 총합이 최소가 되는 경우가 지금까지 걸린 시간의 총합이 되는 경우가 아닐 수 있다. 즉 부분의 최적이 전체의 최적임이 보장이 안된다. 이 경우는 DP가 성립이 안된다. 추가적으로 관찰을 해야한다. 내가 맨처음에 5만큼을 이동하였으면 내 남은 모든 장소에 대한 대기시간이 5 증가한다. 따라서 거리 * 남은 시간으로써 고려를 해준다면 항상 현재 시점을 0으로 생각해 줄 수 있다. 그래서 dp[state][i][j] i~j 까지 완료하였고, state의 방향에 있으며 현재 시점을 0으로 생각하여 남은 곳 들을 모두 들리는데 걸리는 대기시간의 최솟값으로 정의를 할 수 있다. 또한 나는 (i,j)에서 (i-1,j) 또는 (i,j+1)로만 이동 가능하다.

시간복잡도는 O(n^2)

코드

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
43
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
 
ll pre[505][505];
ll dp[2][505][505];
ll n;
 
ll sol(ll l,ll r,ll pos){
    if(dp[pos][l][r]!=1e18return dp[pos][l][r];
    if(l==1&&r==n) return 0;
    ll &ret=dp[pos][l][r];
    ll now;
    if(pos==0) now=l;
    else now=r;
    if(l>1)
        ret=min ( sol(l-1,r,0)+pre[l-1][now]* (n-(r-l+1)),ret);
    if(r<n)
        ret=min (ret, sol(l,r+1,1)+pre[now][r+1]*(n-(r-l+1)) );
    return ret;
}  
 
int main(){
    ll t;
    scanf("%lld",&t);
    while(t--){
        ll i,j,k,l,m;
        scanf("%lld %lld",&n,&m);
        for(i=1;i<n;i++)
            scanf("%lld",&pre[i][i+1]);
        
        for(i=1;i<=n;i++)
            for(j=i+2;j<=n;j++)
                pre[i][j]=pre[i][j-1]+pre[j-1][j];
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++){
                dp[0][i][j]=1e18;
                dp[1][i][j]=1e18;
            }
        printf("%lld\n",min(sol(m,m,0),sol(m,m,1)));
        
    }
}
cs

'코딩 > 백준 문제 풀이' 카테고리의 다른 글

BOJ 1006 - 습격자 초라기  (0) 2020.02.09
BOJ 1520 - 내리막 길  (0) 2020.01.24
BOJ 1848 - 동굴 탐험  (0) 2019.11.25
BOJ 1753 - 최단경로  (0) 2019.11.24
BOJ 1260 - DFS와 BFS  (0) 2019.11.19