jujuwon
시크릿주주
jujuwon
전체 방문자
오늘
어제
  • 분류 전체보기 (106)
    • 🔠 프로그래밍언어 (35)
      • ☕️ Java (19)
      • 🐠 Python (15)
      • 🍠 Kotlin (1)
    • 🔙 Backend (16)
      • 🌿 Springboot (12)
      • 🐳 Docker (1)
      • ☁️ AWS (3)
    • 💼 CS (12)
      • 📶 Network (12)
    • 🕹 알고리즘 (14)
      • 📑 스터디 (2)
      • 💁🏻‍♂️ 백준 (9)
      • 👨🏼‍🔬 프로그래머스 (3)
    • 📚 Book (8)
      • 🔎 오브젝트 (4)
      • 🧪 TDD (2)
      • 📜 논문 (2)
    • 🔐 보안 (7)
      • 👾 Pwnable (7)
    • 📝 회고 (4)
    • 🧩 etc. (10)
      • ⚠️ issue (2)
      • 💡 꿀팁 (7)
      • ✏️ 끄적 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

hELLO · Designed By 정상우.
jujuwon

시크릿주주

백준 :: 7570번 줄 세우기 (Python)
🕹 알고리즘/💁🏻‍♂️ 백준

백준 :: 7570번 줄 세우기 (Python)

2023. 5. 25. 10:51
반응형

문제 링크

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

 

7570번: 줄 세우기

입력은 2 개의 줄로 이루어져 있다. 첫 줄에는 어린이 수를 나타내는 정수가 주어진다. 둘째 줄에는 처음에 줄서있는 어린이들의 번호가 차례대로 주어진다. 주어진 번호들 사이에는 공백이 하

www.acmicpc.net

접근 방식

정렬을 하려고 삽질을 하다가 결국 다른 분들의 풀이를 참조했던 문제 ..

제일 앞이나 제일 뒤로 보내는 어린이의 수를 구하기 위해서는 현재 어린이들 중에서

잘 서 있는 어린이의 수와, 잘못 서있는 어린이의 수를 구하면 된다.

예를 들어 예제 입력으로 나온 5 2 4 1 3 의 경우 2번과 3번은 “잘 서 있다” 라고 말할 수 있다.

그 외의 5, 4, 1번의 어린이는 제일 앞이나 뒤로 이동해서 위치를 바꾸어야 한다.

여기서 LIS (Longest Increasing Subsequence) 를 알고 있다면 풀이에 빠르게 접근할 수 있는데,

이 문제에서는 연속된 수를 가진 가장 긴 증가수열을 찾으면 된다.

다른 예시로 4 2 1 3 5 라는 순서가 있다면, [2, 3] 이 가장 긴 연속된 증가수열이 되고

나머지 4, 1, 5 는 움직여야 한다는 것을 알 수 있다.

이제 코드를 작성해보았는데, n 의 수가 100만이기 때문에 이중 loop 로는 시간초과가 난다.

각 번호의 위치를 배열 인덱스로 활용하면 O(N^2)는 피할 수 있다.

풀이 코드

import sys

def input():
    return sys.stdin.readline().rstrip()

N = int(input())
children = list(map(int, input().split(' ')))
idx = [0 for _ in range(N + 1)]

for i, v in enumerate(children):
    idx[v] = i

maxval = 0
cnt = 1
for num in range(1, N):
    if idx[num] < idx[num + 1]:
        cnt += 1
    else:
        maxval = max(maxval, cnt)
        cnt = 1

print(N - maxval if N != 1 else 0)

이후 DP 를 이용해서 코드를 다시 짜보았다.

결국 주어진 수들에서 “가장 길게 증가하는, 연속된 부분 수열” 을 구하는 게 중요한데,

각 수마다 하나 앞의 수가 이미 등장했는지를 확인하면서 기록해나간다는 컨셉이 중요하다.

예를 들어 현재 숫자가 2이면, 1이 이전에 나왔는지를 체크하는 방식 !

import sys

def input():
    return sys.stdin.readline().rstrip()

N = int(input())
children = list(map(int, input().split(' ')))

dp = [0 for _ in range(N+1)]
for child in children:
    dp[child] = dp[child - 1] + 1

print(N - max(dp) if N != 1 else 0)

삽질의 흔적.. 확실히 DP를 이용하고 나니까 시간이 절반으로 줄었다.

끝.

728x90
반응형
저작자표시 (새창열림)
    '🕹 알고리즘/💁🏻‍♂️ 백준' 카테고리의 다른 글
    • 백준 :: 1043번 거짓말 (Python)
    • 백준 :: 2493번 탑 (Python)
    • 백준 :: 1213번 팰린드롬 만들기 (Python)
    • 백준 :: 1254번 팰린드롬 만들기 (Python)
    jujuwon
    jujuwon

    티스토리툴바