HTML & JS
// Problem Link :
// https://codingcompetitions.withgoogle.com/kickstart/round/0000000000050edc/000000000018666c

#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

Generated URL:

Output:

Case #1: 3
Case #2: 0
Case #3: 1
Case #4: 2
Report Bug