Fixed Points (Codeforces 1551E)
Tags: DP, binary search

Consider a sequence of integers $$$a_1, a_2, \ldots, a_n$$$. In one move, you can select any element of the sequence and delete it. After an element is deleted, all elements to the right are shifted to the left by $$$1$$$ position, so there are no empty spaces in the sequence. So after you make a move, the sequence's length decreases by $$$1$$$. The indices of the elements after the move are recalculated.E. g. let the sequence be $$$a=[3, 2, 2, 1, 5]$$$. Let's select the element $$$a_3=2$$$ in a move. Then after the move the sequence will be equal to $$$a=[3, 2, 1, 5]$$$, so the $$$3$$$-rd element of the new sequence will be $$$a_3=1$$$ and the $$$4$$$-th element will be $$$a_4=5$$$.You are given a sequence $$$a_1, a_2, \ldots, a_n$$$ and a number $$$k$$$. You need to find the minimum number of moves you have to make so that in the resulting sequence there will be at least $$$k$$$ elements that are equal to their indices, i. e. the resulting sequence $$$b_1, b_2, \ldots, b_m$$$ will contain at least $$$k$$$ indices $$$i$$$ such that $$$b_i = i$$$.

Input: The first line contains one integer $$$t$$$ ($$$1 \le t \le 100$$$) — the number of test cases. Then $$$t$$$ test cases follow.Each test case consists of two consecutive lines. The first line contains two integers $$$n$$$ and $$$k$$$ ($$$1 \le k \le n \le 2000$$$). The second line contains a sequence of integers $$$a_1, a_2, \ldots, a_n$$$ ($$$1 \le a_i \le n$$$). The numbers in the sequence are not necessarily different.It is guaranteed that the sum of $$$n$$$ over all test cases doesn't exceed $$$2000$$$.

Output: For each test case output in a single line:  $$$-1$$$ if there's no desired move sequence;  otherwise, the integer $$$x$$$ ($$$0 \le x \le n$$$) — the minimum number of the moves to be made so that the resulting sequence will contain at least $$$k$$$ elements that are equal to their indices. 

Note: In the first test case the sequence doesn't satisfy the desired condition, but it can be provided by deleting the first element, hence the sequence will be $$$[1, 2, 3, 4, 5, 6]$$$ and $$$6$$$ elements will be equal to their indices.In the second test case there are two ways to get the desired result in $$$2$$$ moves: the first one is to delete the $$$1$$$-st and the $$$3$$$-rd elements so that the sequence will be $$$[1, 2, 3]$$$ and have $$$3$$$ elements equal to their indices; the second way is to delete the $$$2$$$-nd and the $$$3$$$-rd elements to get the sequence $$$[5, 2, 3]$$$ with $$$2$$$ desired elements.

Sample Inputs:
4
7 6
1 1 2 3 4 5 6
5 2
5 1 3 2 3
5 2
5 5 5 5 4
8 4
1 2 3 3 2 2 5 5

Sample Outputs:
1
2
-1
2

Solution (Python):
for _ in range(int(input())):
    (n, k) = map(int, input().split())
    a = list(map(int, input().split()))
    d = []
    for (i, x) in enumerate(a):
        d.append(i - x + 1)
    dp = [-1] * n
    for i in range(n):
        if d[i] < 0:
            continue
        h = 0
        for j in range(0, i):
            if d[i] >= d[j] and a[i] > a[j]:
                h = max(h, dp[j])
        dp[i] = 1 + h
    ans = float('inf')
    for i in range(n):
        if dp[i] == -1:
            continue
        if dp[i] >= k:
            ans = min(ans, d[i])
    if ans == float('inf'):
        ans = -1
    print(ans)

Solution (Python):
def solve():
    (n, k) = map(int, input().split())
    a = list(map(int, input().split()))
    d = [-1000000] * n
    ans = 1000000
    for i in range(n):
        z = -1000000
        v = a[i]
        w = a[i] - i
        if i >= v - 1:
            z = 0
        for j in range(i):
            if a[j] < v and a[j] - j >= w:
                z = max(z, d[j])
        d[i] = z + 1
        if z + 1 >= k:
            ans = min(ans, 1 - w)
    print(-1) if ans >= 1000000 else print(ans)
for i in range(int(input())):
    solve()

Solution (Python):
def solve():
    (n, k) = map(int, input().split())
    a = list(map(int, input().split()))
    d = [-1000000] * n
    ans = 1000000
    for i in range(0, n):
        z = -1000000
        v = a[i]
        w = a[i] - i
        if i >= v - 1:
            z = 0
        for j in range(i):
            if a[j] < v and a[j] - j >= w:
                z = max(z, d[j])
        d[i] = z + 1
        if z + 1 >= k:
            ans = min(ans, 1 - w)
    print(-1) if ans >= 1000000 else print(ans)
for i in range(int(input())):
    solve()