문제
https://www.acmicpc.net/problem/18353
18353번: 병사 배치하기
첫째 줄에 N이 주어진다. (1 ≤ N ≤ 2,000) 둘째 줄에 각 병사의 전투력이 공백을 기준으로 구분되어 차례대로 주어진다. 각 병사의 전투력은 10,000,000보다 작거나 같은 자연수이다.
www.acmicpc.net
문제 요약
N명의 병사들이 무작위로 나열되어 있고, 각 병사들은 전투력을 갖고 있다.
병사를 배치할 때는 전투력이 높은 병사가 앞쪽에 오도록 내림차순으로 배치를 해야한다.
남아 있는 병사의 수가 최대가 되도록 하기 위해서 열외해야 하는 병사의 수를 출력한다.
코드
N = int(input())
arr = list(map(int, input().split()))
dp = [1] * N
# dp[i]는 i 인덱스까지 내림차순한 병사의 최대 수
for i in range(1, N):
for j in range(i):
if arr[j] > arr[i]:
dp[i] = max(dp[j] + 1, dp[i])
print(N - max(dp))
코드 설명
1. i 인덱스까지 가장 긴 감소하는 부분 수열의 개수(병사 최대 수)를 저장하는 메모이제이션 테이블 dp를 생성한다.
2. 0번 인덱스부터 i-1번 인덱스까지 접근하며 이전 인덱스 값 (arr[j]) 보다 자신의 인덱스 (arr[i]) 값이 작으면 dp[j]값에 1을 더한 값과 dp[i]값을 비교하여 큰 값으로 갱신한다.
+ dp[j]에 1을 더한 값: j까지의 가장 긴 감소하는 부분 수열에 자기 자신을 추가한 부분 수열의 개수
3. N - (dp 배열 중 가장 큰 값)을 출력한다.
+ 열외해야 하는 병사의 수 = 전체 병사의 수 - 남아 있는 병사의 수
'Algorithm Problems > 다이나믹 프로그래밍' 카테고리의 다른 글
[백준/Python] 1149번: RGB거리 (0) | 2023.10.03 |
---|---|
[백준/Python] 25706번: 자전거 묘기 (3) | 2023.09.17 |
[백준/Python] 1965번: 상자넣기 (2) | 2023.09.12 |
[백준/Python] 11055번: 가장 큰 증가하는 부분 수열 (2) | 2023.09.06 |
[백준/Python] 21317번: 징검다리 건너기 (2) | 2023.09.01 |