```// Problem Link :

#include<bits/stdc++.h>
using namespace std ;

/*                        [Template]                        */
#define async ios_base::sync_with_stdio(false); cin.tie(NULL);
#define Int long long int
#define let auto
#define of :
#define all(y) y.begin(), y.end()
#define present( x, y ) x.find( y ) != x.end()
#define _matrix(T) vector<vector<T>>
template<class T>
auto matrix( int r, int c, T v ){
return vector<vector<T>>( r, vector<T>( c, v ) ) ;
}
/*                *                         *                */

#define inf (int)1e9
let dp = matrix<int>( 101, 101, -1 ) ;

void refresh(){
dp = matrix<int>( 101, 101, -1 ) ;
}

// this problem is a simple divide problem
// The problem is to divide the heights into groups (at most k + 1 group)
// of similar or different heights
// two consecutive groups here can have similar height because
// they will represent one group after merging them making the total number of groups to k which is within our limits of at most k + 1 groups

int rec( _matrix(int) &R, int &N, int i, int k ){
if( i >= N - 1 ) return 0 ;   // base case
if( k == 0 ) return dp[i][k] = R[i][N-1] ; // we are in the last group cannot ask further so returning the minimum cost for making all the heights same
if( dp[i][k] != -1 ) return dp[i][k] ;       // using the power of dynammic programming
int mn = inf ;
for( int j = i + 1 ; j < N ; j++ ){  // making groups from [ i : j - 1 ] and asking for the rest
mn = min( mn, R[i][j - 1] + rec( R, N, j, k - 1 ) ) ;  // cost of current group + asking for cost of rest of the heights
}
return dp[i][k] = mn ;   // returing the optimal cost
}

int solve(){
int n, k ; cin >> n >> k ;
vector<int> heights(n) ;
for( let &height of heights ) cin >> height ;
// R[i][j] will store minimum number of moves to make all the heights same for range [ i : j ] both inclusive
let R = matrix<int>( n, n, 0 ) ;
map<int,int> mp ;
for( int i = 0 ; i < n ; i++ ){
mp.clear() ;
int mx = 0 ;
for( int j = i ; j < n ; j++ ){
mp[ heights[j] ]++ ;
mx = max( mx, mp[heights[j]] ) ; // maximum frequency can be either old or frequency of this element
R[i][j] = ( j - i + 1 ) - mx ;   // read the first paragraph of official analysis for better understanding
}
}
return rec( R, n, 0, k ) ;
}

signed main(){
int T ; cin >> T ;
for( int test = 1 ; test <= T ; test++ ){
refresh() ;
cout << "Case #" << test << ": " << solve() << "\n" ;
}
return 0 ;
}

// i am sharing a link of somewhat similar question for practice ( and the solution too )
// so that you can understand if you have understood the problem or not
// https://www.codechef.com/AUG20B/problems/CHEFWED
// try to do it recursively for a better understanding. :-)
// solution :
// https://www.codechef.com/viewsolution/36614281
```

### Output:

```Case #1: 3
Case #2: 0
Case #3: 1
Case #4: 2
```