본문 바로가기

알고리즘

BOJ 14462 소가 길을 건너간 이유 8

https://www.acmicpc.net/problem/14462

 

14462번: 소가 길을 건너간 이유 8

존 (우리가 지금까지 도와 주었던 존과는 다른 인물이다)의 농장에는 N 종류의 소가 있다. 각각 1번 종, 2번 종, ..., N번 종 (1 ≤ N ≤ 1000)이다. 만약 |a−b| ≤ 4라면 a번 종과 b번 종의 소는 친하지만

www.acmicpc.net

 

 

왼쪽의 i 번째 소, 오른쪽의 j 번째 소를 이을려고 할 때 (물론 두 소가 친한 경우에) 어떻게 해야할 까 생각해보니,
DP로 풀면 되겠다고 생각했다.

왜냐하면, i 번째 소, j 번째 소를 이을 때, 
[ 0,0 ] ~ [ i - 1, j - 1 ]  조합 중 가장 많은 소를 연결하는 경우에 더해  i , j 를 잇기만 하면 되기 때문에, DP 라고 생각했다.

 

점화식은 다음과 같다.

친한 소의 경우
$$ DP[i][j] = DP[i-1][j-1] + 1  $$

안 친한 소의 경우
$$ DP[i][j] = max(DP[i][j-1] , DP[i-1][j], DP[i-1][j-1] )  $$

 

코드는 아래와 같다.

#include <cstdio>
#include <algorithm>

int n, ans;
int arr[2000], dp[1000][1000];

bool cmp(int a, int b){ return std::abs(a-b) <= 4; }

int main(){

    scanf("%d",&n);
    for(int i=0;i<2*n;i++) scanf("%d",arr+i);
    
    if(cmp(arr[0], arr[n])) dp[0][0] = 1;
    for(int i=1;i<n;i++){
        if(cmp(arr[0], arr[i+n]) || dp[0][i-1]) dp[0][i] = 1;
        if(cmp(arr[i],arr[n])    || dp[i-1][0]) dp[i][0] = 1;
    }

    for(int i=1;i<n;i++){
        for(int j=1;j<n;j++){
            if(cmp(arr[i], arr[n+j])){ 
                dp[i][j] = dp[i-1][j-1] + 1;
            }
            dp[i][j] = std::max(dp[i][j], std::max(dp[i-1][j-1], std::max(dp[i-1][j], dp[i][j-1])));
            if(dp[i][j] > ans) ans = dp[i][j];
        }
    } 

    printf("%d\n",ans);

    return 0;
}

 

 

 

'알고리즘' 카테고리의 다른 글

BOJ 15590 Rental Service  (0) 2022.09.25
BOJ 12011 Splitting the Field  (0) 2022.06.22
BOJ 14451 안대 낀 스피드러너  (0) 2022.05.24
BOJ 11983 Radio Contact  (0) 2022.04.21
BOJ 11968 High Card Wins  (0) 2022.04.20