-
백준 2618번 경찰차 (boj/2618.c)R&E: research & education/PS 2024. 1. 14. 13:42
DP문제입니다. 공간복잡도 O(W^2), 시간복잡도 O(W^2)으로 해결가능합니다.
또한 각 사건마다 할당된 경찰관을 묻고 있기 때문에 간단한 자취 남기기 기법을 응용합니다.
DP의 구성은 아래와 같습니다.
회색 영역은 초기화 때 계산됩니다.
빗금 영역에 있는 값 중 최소의 값을 문제의 답으로 결정합니다.
한 번에 계산되는 양은 아래와 같습니다.
코드는 아래와 같습니다.
#include <stdio.h> #include <math.h> #define SZE 1000 int dp[SZE+1][SZE+1]; int idx[SZE+1][2]; int giv[SZE+1] = { 0, }; typedef struct _p{ int row; int col; }point; point loc[SZE+1]; int get_dst(point p1, point p2){ return abs(p1.row-p2.row) + abs(p1.col-p2.col); } int main(void){ int N, W; int row, col, tmp; int cur_row, cur_col, rec; int res; point pol1, pol2; scanf("%d %d", &N, &W); pol1.row=pol1.col=1; pol2.row=pol2.col=N; for(int i=1;i<=W;i++){ scanf("%d %d", &row, &col); loc[i].row=row; loc[i].col=col; } //gray area (tmp = length loc1 to loci) tmp = 0; for(int i=1;i<=W;i++){ if(i>1){ tmp += get_dst(loc[i-1], loc[i]); } dp[0][0] = 0; dp[i][0] = get_dst(pol1, loc[1]) + tmp; dp[0][i] = get_dst(pol2, loc[1]) + tmp; } for(int i=1;i<W;i++){ //black area dp[i][i]=-1; //dark green area dp[i][i+1] = dp[i][0] + get_dst(pol2, loc[i+1]); idx[i][1] = 0; for(int j=1;j<i;j++){ tmp = dp[i][j] + get_dst(loc[j], loc[i+1]); if(tmp < dp[i][i+1]){ dp[i][i+1] = tmp; idx[i][1]=j; } } //dark red area for(int j=i+2;j<=W;j++){ dp[i][j] = dp[i][j-1] + get_dst(loc[j-1], loc[j]); } //light green area dp[i+1][i] = dp[0][i] + get_dst(pol1, loc[i+1]); idx[i+1][0] = 0; for(int j=1;j<i;j++){ tmp = dp[j][i] + get_dst(loc[j], loc[i+1]); if(tmp < dp[i+1][i]){ dp[i+1][i]=tmp; idx[i+1][0]=j; } } //light red area for(int j=i+2;j<=W;j++){ dp[j][i] = dp[j-1][i] + get_dst(loc[j-1], loc[j]); } } //search answer res = dp[0][W]; for(int i=0;i<W;i++){ if(res > dp[i][W]){ res = dp[i][W]; cur_row=i; cur_col=W; } if(res > dp[W][i]){ res = dp[W][i]; cur_row=W; cur_col=i; } } //make path rec=W; while(rec--){ if(cur_row > cur_col+1){ giv[rec] = 1; cur_row--; } else if(cur_row == cur_col+1){ giv[rec] = 1; cur_row=idx[cur_row][0]; } else if(cur_row+1 == cur_col){ giv[rec] = 2; cur_col=idx[cur_row][1]; } else if(cur_row+1 < cur_col){ giv[rec] = 2; cur_col--; } else{ giv[rec]=-1; } } printf("%d\n", res); for(int i=0;i<W;i++){ printf("%d\n", giv[i]); } return 0; }
'R&E: research & education > PS' 카테고리의 다른 글
백준 6987번 월드컵 (boj/6987.c) (0) 2024.01.23 백준 1310번 달리기 코스 (boj/1310.cpp) (1) 2024.01.22 백준 13977번 이항 계수와 쿼리 (boj/13977.c) (1) 2024.01.21 백준 1786번 찾기 (boj/1786.c) (0) 2024.01.18 백준 3015번 오아시스 재결합 (boj/3015.c) (0) 2024.01.15