공부/백준

백준 2565번: 전깃줄(C++)

상연 2020. 11. 26. 23:05

목차

    www.acmicpc.net/problem/2565

     

    2565번: 전깃줄

    첫째 줄에는 두 전봇대 사이의 전깃줄의 개수가 주어진다. 전깃줄의 개수는 100 이하의 자연수이다. 둘째 줄부터 한 줄에 하나씩 전깃줄이 A전봇대와 연결되는 위치의 번호와 B전봇대와 연결되는

    www.acmicpc.net

    코드

    #include <iostream>
    using namespace std;
    
    int line[501] = {0, };
    int dp[501] = {0, };
    int n;
    int min_idx = 1000;
    int max_idx = -1000;
    void init(){
      cin >> n;
      int idx;
      for(int i=0; i<n; i++){
        cin >> idx;
        min_idx = idx < min_idx ? idx : min_idx;
        max_idx = idx > max_idx ? idx : max_idx;
        cin >> line[idx];
      }
    }
    
    void solve(){
      int max_num = 0;
      for(int i=min_idx; i<=max_idx; i++){
        if(line[i] == 0) dp[i] = 0;
        else dp[i] = 1;
        for(int j=min_idx; j<i; j++){
          if(line[i] > line[j]){
            dp[i] = dp[i] > dp[j] + 1 ? dp[i] : dp[j] + 1;}
          }
          max_num = dp[i] > max_num ? dp[i] : max_num;
        }
        cout << (n - max_num);
    }
    
    int main(){
      init();
      solve();
    }
    

    풀이

    괜히 어... 전깃줄이 교차되어있고... 그럼 이걸 제거하는게 더 이득인가 저걸 제거하는게 이득인가..?

    재면서 생각하면 더 어려운 문제입니다. 간단하게 생각하시면 이전에 푼 '가장 긴 증가하는 수열' 과 같습니다.

    wonsang98.tistory.com/77

     

    백준 11053번: 가장 긴 증가하는 부분 수열(C++)

    www.acmicpc.net/problem/11053 11053번: 가장 긴 증가하는 부분 수열 수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인..

    wonsang98.tistory.com

     

    무슨 의미냐 하면

    주어진 N 개의 전깃줄이 있습니다. 문제의 입출력 예시에 따르면 

    8
    1 8
    3 9
    2 2
    4 1
    6 4
    10 10
    9 7
    7 6

    이 입력이 되며, 이 입력에 따른 입력결과는 아래 그림과 같습니다.

    배열로 치면 A는 배열의 index라 하고, B는 index에 대응되는 값이라고 하겠습니다. (배열 arr[Ai] = Bi)

    그렇다면 배열은 이렇게 정리가 되겠죠.

    이제 간단합니다. 가장 작은 idx ~ 가장 큰 idx 내에서 '가장 긴 증가하는 부분 수열'의 길이를 구한 후

    주어진 전깃줄의 수 N에서 빼주면 정답이 됩니다. 

    증가하는 부분 수열은 곧, 전깃줄이 겹치지 않게 배열하는 것 중 가장 긴 수열과 같기 때문입니다.