N = int(input())
num = [list(map(int, input().split())) for _ in range(N)]
# 두개의 메모이제이션 공간 사용
dp1 = [1 for _ in range(N)] # 정방향 증가 메모이제이션 공간
dp2 = [1 for _ in range(N)] # 역방향 증가 메모이제이션 공간
for i in range(N):
for j in range(i):
# 정방향 증가 최장 순열
if (num[i][0] > num[j][0]) & (num[i][1] > num[j][1]):
dp1[i] = max(dp1[i], dp1[j] + 1)
# 역방향 증가 최장 순열
if (num[N - 1 - i][0] > num[N - 1 - j][0]) &\
(num[N - 1 - i][1] > num[N - 1 - j][1]):
dp2[N - 1 - i] = max(dp2[N - 1 - i], dp2[N - 1 - j] + 1)
dp = [dp1[i] + dp2[i] - 1 for i in range(N)]
print(N - max(dp))
dp1 = [1 for _ in range(N)]
dp2 = [1 for _ in range(N)]
dp3 = [1 for _ in range(N)]
dp4 = [1 for _ in range(N)]
for i in range(N):
for j in range(i):
if (num[i][0] > num[j][0]) & (num[i][1] > num[j][1]):
dp1[i] = max(dp1[i], dp1[j] + 1)
elif (num[i][0] < num[j][0]) & (num[i][1] < num[j][1]):
dp3[i] = max(dp3[i], dp3[j] + 1)
if (num[N - 1 - i][0] > num[N - 1 - j][0]) &\
(num[N - 1 - i][1] > num[N - 1 - j][1]):
dp2[N - 1 - i] = max(dp2[N - 1 - i], dp2[N - 1 - j] + 1)
elif (num[N - 1 - i][0] < num[N - 1 - j][0]) &\
(num[N - 1 - i][1] < num[N - 1 - j][1]):
dp4[N - 1 - i] = max(dp4[N - 1 - i], dp4[N - 1 - j] + 1)
dp090 = [dp1[i] + dp2[i] - 1 for i in range(N)]
dp909 = [dp3[i] + dp4[i] - 1 for i in range(N)]
print(N - max(dp090 + dp909))
따라서, 위의 경우처럼 감소했다 증가하는 경우를 고려하기 위해 dp3, dp4를 추가 하였다. 그러나 해당 방식도 오답이다.
그렇다! 증가했다가 감소하는 경우(봉우리 형태)와 감소 했다가 증가한느 경우(골짜기 형태) 외에 고려해야 할 형태가 하나 더 있다. 바로 지그재그 형태 이다. 따라서 다음과 같은 숫자가 오면 오답을 출력하게 된다.
9
1 1
9 9
2 2
8 8
3 3
7 7
4 4
6 6
5 5
num = sorted(num) # 2중 list에서 sorted function을 적용하면 각 list의 첫번째 요소를 기준으로 정렬한다.
dp = [1 for _ in range(N)]
for i in range(N):
for j in range(i):
if num[i][1] > num[j][1]:
dp[i] = max(dp[i], dp[j] + 1)
print(N - max(dp))