만드는 중입니다

아직 만드는 중이라 바뀔 수 있습니다

배열 정렬하기 (Large)

시간 제한30초메모리 제한512 MB

요약
1부터 N까지의 순열과 P가 주어질 때, 연속한 블록으로 나눠 각각 정렬하고 최대 P개의 블록만 서로 바꿔 전체를 정렬할 수 있는 최대 블록 수를 구한다.
난이도

어려움10점 중 8점

유형
그리디, 정렬, 구현, 조합론
정답자
아직 제출이 없습니다

문제

1부터 NN까지의 정수가 한 번씩 들어 있는 배열 AA를 정렬하는 조금 특이한 알고리즘을 만들고 있다. AA의 정수는 처음에 임의의 순서로 놓여 있다. 이 알고리즘은 입력 순서 외에 두 정수 PP와 KK에 따라 동작한다. 알고리즘은 다음과 같다.

  1. AA를 비어 있지 않은 연속 부분 배열 KK개 A1,A2,…,AKA_1, A_2, \ldots, A_K로 나눈다. 이 부분 배열을 순서대로 이어 붙인 A1A2…AKA_1A_2 \ldots A_K는 AA와 같아야 한다.
  2. 각 부분 배열을 따로 정렬한다.
  3. 부분 배열을 최대 PP개 고르고, 고른 부분 배열 가운데 두 개를 맞바꾸는 일을 원하는 만큼 반복한다. 고르지 않은 부분 배열은 제자리에 남는다.

예를 들어 A=[1 5 4 3 2]A = [1\ 5\ 4\ 3\ 2]이고 P=2P = 2라고 하자. K=4K = 4개로 나누는 방법 하나는 다음과 같다.

A1 = [1]
A2 = [5]
A3 = [4]
A4 = [3 2]

각 부분 배열을 정렬한 뒤:

A1 = [1]
A2 = [5]
A3 = [4]
A4 = [2 3]

A4와 A2를 맞바꾼 뒤:

A1 = [1]
A2 = [2 3]
A3 = [4]
A4 = [5]

이 알고리즘이 분산 환경에 잘 맞는다는 것을 보이려고 한다. 입력 배열과 PP가 주어질 때, 부분 배열 나누기와 맞바꾸기를 잘 골라서 AA를 정렬할 수 있는 KK의 최댓값을 구하라.

입력

첫째 줄에 테스트 케이스의 수 TT가 주어진다.

이어서 TT개의 테스트 케이스가 주어지며, 각 테스트 케이스는 두 줄로 이루어진다. 첫째 줄에는 두 정수 NN과 PP가 주어진다.

둘째 줄에는 배열 AA를 나타내는 NN개의 정수 X1,X2,…,XNX_1, X_2, \ldots, X_N이 주어진다.

출력

각 테스트 케이스마다 Case #x: y 형식으로 한 줄을 출력한다. x는 1부터 시작하는 테스트 케이스 번호이고 y는 가능한 KK의 최댓값이다.

제한

  • 1≤T≤1001 \le T \le 100
  • 1≤N≤50001 \le N \le 5000
  • 1≤P≤31 \le P \le 3
  • 모든 ii에 대해 1≤Xi≤N1 \le X_i \le N
  • i≠ji \ne j이면 Xi≠XjX_i \ne X_j

노트

1번 케이스: 문제 설명의 예시와 같다.

2번 케이스:

[4 5] [1 2 3]
두 부분 배열을 맞바꾸면: [1 2 3] [4 5]

3번 케이스:

[6] [3 5 2 4] [1]
[3 5 2 4]를 정렬하고 [6]과 [1]을 맞바꾸면: [1] [2 3 4 5] [6]

4번 케이스:

[4 5] [1] [2 3]
[4 5]와 [1]을 맞바꾸고 다시 [2 3]과 [4 5]를 맞바꾸면: [1] [2 3] [4 5]

5번 케이스:

[1] [2] [6] [4] [5] [3]
[6]과 [3]을 맞바꾸면: [1] [2] [3] [4] [5] [6]

예제1

  1. 예제 1

    입력
    5
    5 2
    1 5 4 3 2
    5 2
    4 5 1 2 3
    6 2
    6 3 5 2 4 1
    5 3
    4 5 1 2 3
    6 3
    1 2 6 4 5 3
    
    예상 출력
    Case #1: 4
    Case #2: 2
    Case #3: 3
    Case #4: 3
    Case #5: 6