Problem:
Optimal Tournament
In 21XX, an annual programming contest "Japan Algorithmist GrandPrix (JAG)" has been one of the most popular mind sport events. You, the chairperson of JAG, are preparing this year's JAG competition.
JAG is conducted as a knockout tournament. This year, $N$ contestants will compete in JAG. A tournament is represented as a binary tree having $N$ leaf nodes, to which the contestants are allocated one-to-one. In each match, two contestants compete. The winner proceeds to the next round, and the loser is eliminated from the tournament. The only contestant surviving over the other contestants is the champion. The final match corresponds to the root node of the binary tree.
You know the strength of each contestant, $A_1,A_2, ..., A_N$, which is represented as an integer. When two contestants compete, the one having greater strength always wins. If their strengths are the same, the winner is determined randomly.
In the past JAG, some audience complained that there were too many boring one-sided games. To make JAG more attractive, you want to find a good tournament configuration.
Let's define the boringness of a match and a tournament. For a match in which the $i$-th contestant and the $j$-th contestant compete, we define the boringness of the match as the difference of the strength of the two contestants, $|A_i - A_j|$. And the boringness of a tournament is defined as the sum of the boringness of all matches in the tournament.
Your purpose is to minimize the boringness of the tournament.
You may consider any shape of the tournament, including unbalanced ones, under the constraint that the height of the tournament must be less than or equal to $K$. The height of the tournament is defined as the maximum number of the matches on the simple path from the root node to any of the leaf nodes of the binary tree.
Figure K-1 shows two possible tournaments for Sample Input 1. The height of the left one is 2, and the height of the right one is 3.
Write a program that calculates the minimum boringness of the tournament.
Input
The input consists of a single test case with the following format.
$N$ $K$
$A_1$ $A_2$ ... $A_N$
The first line of the input contains two integers $N$ ($2 \leq N \leq 1,000$) and $K$ ($1 \leq K \leq 50$). You can assume that $N \leq 2^K$. The second line contains $N$ integers $A_1, A_2,  ..., A_N$. $A_i$ ($1 \leq A_i \leq 100,000$) represents the strength of the $i$-th contestant.
Output
Output the minimum boringness value achieved by the optimal tournament configuration.
Sample Input 1
4 3
1 3 4 7
Output for the Sample Input 1
6
Sample Input 2
5 3
1 3 4 7 9
Output for the Sample Input 2
10
Sample Input 3
18 7
67 64 52 18 39 92 84 66 19 64 1 66 35 34 45 2 79 34
Output for the Sample Input 3
114

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
const int INF = 1e9;
int n, K;
int s[MAXN];
int f[MAXN][MAXN][55], g[MAXN][MAXN][55];

int main() {
    scanf("%d %d", &n, &K);
    for (int i = 1; i <= n; i++)
        scanf("%d", s + i);
    sort(s + 1, s + n + 1);

    for (int i = 1; i <= n; i++)
        for (int j = i; j <= n; j++)
            for (int k = 0; k <= K; k++)
                f[i][j][k] = INF;
    for (int i = 1; i <= n; i++)
        for (int j = 0; j <= K; j++)
            f[i][i][j] = 0, g[i][i][j] = i;

    for (int d = 1; d < n; d++)
        for (int i = 1; i + d <= n; i++) {
            int j = i + d;
            for (int k = 1; k <= K; k++) {
                f[i][j][k] = f[i][j][k - 1];
                g[i][j][k] = g[i][j][k - 1];
                for (int l = g[i][j - 1][k]; l <= min(j - 1, g[i + 1][j][k]); l++)
                    if (f[i][j][k] > f[i][l][k - 1] + f[l + 1][j][k - 1] + s[j] - s[l]) {
                        f[i][j][k] = f[i][l][k - 1] + f[l + 1][j][k - 1] + s[j] - s[l];
                        g[i][j][k] = l;
                    }
            }
        }
    printf("%d\n", f[1][n][K]);
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 425156
final_rank: 8

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define LL __int64

using namespace std;

const int Maxn=1e3+10,INF=1e9+10;
int n,m,a[Maxn],f[Maxn][Maxn][60],p[Maxn],g[Maxn][Maxn][60];

int main()
{
    for (int i=2,j=1; i<=1000; i*=2,j++)
    {
        p[i]=j;
        for (int k=i+1; k<=min(1000,i*2-1); k++) p[k]=j+1;
    }
    for ( ; scanf("%d%d",&n,&m)!=EOF; )
    {
        for (int i=1; i<=n; i++) scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        for (int i=1; i<=n; i++)
        for (int x=0; x<=m; x++) f[i][i][x]=0,g[i][i][x]=i;
        for (int len=2; len<=n; len++)
        for (int i=1; i<=n-len+1; i++)
        {
            int j=i+len-1;
            for (int x=0; x<=m; x++)
            {
                f[i][j][x]=INF;
                if (x<p[j-i+1]) continue;
                for (int k=g[i][j-1][x]; k<=g[i+1][j][x]; k++)
                {
                    int u=f[i][k][x-1]+f[k+1][j][x-1]+a[j]-a[k];
                    if (u<f[i][j][x]) f[i][j][x]=u,g[i][j][x]=k;
                }
            }
            for (int x=1; x<=m; x++) if (f[i][j][x-1]<f[i][j][x]) f[i][j][x]=f[i][j][x-1];
        }
//        for (int i=1; i<=n; i++)
//        {
//            for (int j=1; j<=n; j++) printf("%4d",g[i][j][1]);
//            printf("\n");
//        }
        printf("%d\n",f[1][n][m]);
    }
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 465532
final_rank: 11

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE  1005

int N,K;
ll dp[2][SIZE][SIZE];
ll MID[2][SIZE][SIZE];
ll A[SIZE];


int main(){

	scanf("%d %d",&N,&K);

	for(int i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}

	sort(A,A+N);

	int CURRENT = 0,NEXT = 1;

	for(int left = 0; left <= N-1; left++){
		for(int right = left; right <= N-1; right++){

			if(left == right){

				dp[CURRENT][left][right] = 0;

			}else{

				dp[CURRENT][left][right] = HUGE_NUM;
			}
		}
	}

	ll ans = HUGE_NUM;
	int right,L,R;

	for(int height = 1; height <= K; height++){

		for(int left = 0; left <= N-1; left++){
			for(int right = left; right <= N-1; right++){

				if(left == right){

					MID[CURRENT][left][right] = left;
					dp[NEXT][left][right] = dp[CURRENT][left][right];

				}else{

					dp[NEXT][left][right] = HUGE_NUM;
				}
			}
		}

		for(int length = 2; length <= N; length++){
			for(int left = 0; left+length-1 <= N-1; left++){

				right = left+length-1;

				L = MID[CURRENT][left][right-1];
				R = MID[CURRENT][left+1][right];

				for(int mid = L; mid <= R; mid++){

					if(dp[NEXT][left][right] > dp[CURRENT][left][mid]+dp[CURRENT][mid+1][right]+(A[right]-A[mid])){
						dp[NEXT][left][right] = dp[CURRENT][left][mid]+dp[CURRENT][mid+1][right]+(A[right]-A[mid]);
						MID[CURRENT][left][right] = mid;
					}
				}
			}
		}

		ans = min(ans,dp[NEXT][0][N-1]);

		swap(CURRENT,NEXT);
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 34528
final_rank: 2

code_snippet: // AOJ 2737 Optimal Tournament
// 2025.3.2

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1e15;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

ll dp[2][1001][1001];

int main() {
    int N = Cin(), K = Cin();

    vector<ll> a(N);
    for (int i = 0; i < N; i++) a[i] = Cin();
    sort(a.begin(), a.end());

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) dp[0][i][j] = (i == j? 0: INF);
    }

    int s = 0, d = 1;
    for (int h = 1; h <= K; h++, s = d, d = !d) {
        for (int l = 1; l <= N; l++) {
            for (int i = 0; i+l-1 < N; i++) {
                int j = i+l-1;
                if(l == 1) dp[d][i][j] = 0;
                else {
                    ll t = dp[s][i][j];
                    for (int m = i; m < j; m++) {
                        ll c = dp[s][i][m] + dp[s][m+1][j] + (a[j]-a[m]);
                        t = min(t, c);
                    }
                    dp[d][i][j] = t;
                }
            }
        }
    }
    Cout(dp[s][0][N-1]);
    return 0;
}
accuracy: 1
time_ms: 4870
memory_kb: 18208
final_rank: 9

code_snippet: // AOJ 2737 Optimal Tournament
// 2025.3.2

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1e15;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

ll dp0[1001][1001], dp1[1001][1001];

int main() {
    int N = Cin(), K = Cin();

    vector<ll> a(N);
    for (int i = 0; i < N; i++) a[i] = Cin();
    sort(a.begin(), a.end());

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) dp0[i][j] = (i == j? 0: INF);
    }

    for (int h = 1; h <= K; h++) {
        for (int l = 1; l <= N; l++) {
            for (int i = 0; i+l-1 < N; i++) {
                int j = i+l-1;
                if(l == 1) dp1[i][j] = 0;
                else {
                    ll t = dp0[i][j];
                    for (int m = i; m < j; m++) {
                        ll c = dp0[i][m] + dp0[m+1][j] + (a[j]-a[m]);
                        t = min(t, c);
                    }
                    dp1[i][j] = t;
                }
            }
        }
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) dp0[i][j] = dp1[i][j];
        }
    }
    Cout(dp0[0][N-1]);
    return 0;
}
accuracy: 1
time_ms: 4900
memory_kb: 18768
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(v) v.begin(), v.end()
#define rng(i, l, r) for(int i = int(l); i < int(r); i++)
#define rep(i, n) rng(i, 0, n)
#define sz(v) int(v.size())
#define foa(s, v) for(auto& s : v)
int n, k;
constexpr ll INF = 1e18;

template <class T>
bool chmin(T& a, T b) {
	return a > b ? a = b, 1 : 0;
}

template <class T>
bool chmax(T& a, T b) {
	return a < b ? a = b, 1 : 0;
}

#define debug(x) void(0)

template <class T>
ostream& operator<<(ostream& os, vector<T> vec) {
	os << "{ ";
	foa(row, vec) os << row << ", ";
	os << "}";
	return os;
}

template <class T>
ostream& operator<<(ostream& os, vector<vector<T>> vec) {
	os << "{ ";
	foa(row, vec) os << "\n\t" << row << ", ";
	os << "\n}";
	return os;
}

void solve() {
	vector<ll> a(n);
	foa(c, a) cin >> c;
	sort(all(a));

	vector dp(n + 1, vector(n + 1, INF));
	vector mid(k + 1, vector(n + 1, vector<int>(n + 1)));
	rep(left, n) { dp[left][left + 1] = 0LL; }
	rep(lef, n) rng(right, lef + 1, n + 1) { mid.front()[lef][right] = lef + 1; }

	// rep(left, n - 1) dp[left][left + 2] = a[left + 1] - a[left];

	rep(cut, k) {
		vector tmp = dp;
		mid[cut + 1] = mid[cut];
		auto& m = mid[cut+1];

		rng(len, 2, n + 1) {
			rep(lef, n) {
				int right = lef + len;
				if(right > n) break;

				for(int j = m[lef][right - 1]; j <= m[lef + 1][right]; j++) {
					debug(j);
					if(chmin(tmp[lef][right], dp[lef][j] + dp[j][right] + (a[right - 1] - a[j - 1]))) {
						m[lef][right] = j;
					}
				}
			}
		}

		swap(tmp, dp);
	}

	cout << dp[0][n] << endl;
}

int main() {
	while(cin >> n >> k && n) solve();
}
accuracy: 1
time_ms: 320
memory_kb: 184832
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=1005,INF=1<<28;

int dp[53][MAX][MAX];
int pos[53][MAX][MAX];

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int N,K;cin>>N>>K;
    vector<int> A(N);
    for(int i=0;i<N;i++) cin>>A[i];
    sort(all(A));
    
    for(int t=0;t<=K;t++){
        for(int i=0;i<=N;i++){
            for(int j=0;j<=N;j++){
                dp[t][i][j]=INF;
            }
            dp[t][i][i+1]=0;
            pos[t][i][i+1]=i;
        }
    }
    
    for(int t=1;t<=K;t++){
        for(int len=2;len<=N;len++){
            for(int l=0;l<N;l++){
                int r=l+len;
                if(r>N) break;
                for(int m=pos[t][l][r-1];m<=pos[t][l+1][r];m++){
                    if(m-l==0||r-m==0) continue;
                    int co=dp[t-1][l][m]+dp[t-1][m][r]+A[r-1]-A[m-1];
                    if(chmin(dp[t][l][r],co)){
                        pos[t][l][r]=m;
                    }
                }
            }
        }
    }
    
    cout<<dp[K][0][N]<<endl;
}
accuracy: 1
time_ms: 130
memory_kb: 408644
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
const int N=1005,inf=1e9;
int n,k,a[N],dp[2][N][N],t[2][N][N];
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	sort(a+1,a+n+1);
	for(int l=1;l<=n;l++)
		for(int r=1;r<=n;r++)
			dp[0][l][r]=inf;
	for(int i=1;i<=n;i++)
		dp[0][i][i]=0;
	for(int x=1;x<=k;x++)
	{
		int p=(x&1),q=(p^1);
		for(int l=1;l<=n;l++)
			for(int r=1;r<=n;r++)
				dp[p][l][r]=inf;
		for(int h=1;h<=n;h++)
		{
			for(int l=1;l+h-1<=n;l++)
			{
				int r=l+h-1;
				if(l==r)
				{
					dp[p][l][r]=0;
					t[p][l][r]=l;
					continue;
				}
				t[p][l][r]=l;
				for(int i=t[p][l][r-1];i<=t[p][l+1][r];i++)
				{
					int v=dp[q][l][i]+dp[q][i+1][r]+a[r]-a[i];
					if(v<dp[p][l][r])
					{
						dp[p][l][r]=v;
						t[p][l][r]=i;
					}
				}
			}
		}
	}
	printf("%d\n",dp[k&1][1][n]);
	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 19216
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
 
int N,K;
int dp[2][1001][1001];
int dm[2][1001][1001];
int a[1000];
 
int main(){
  scanf("%d %d",&N,&K);
  for(int i=0;i<N;i++)scanf("%d",&a[i]);
  sort(a,a+N);
  fill( (int*)dp[0], (int*)dp[1], 1e9);
  int ans=1e9;
  for(int T=1;T<=K;T++){
    int t=T%2;
    int u=1-t;
    for(int i=0;i<N;i++){
      dp[0][i][i+1]=0;
      dp[1][i][i+1]=0;
    }
    for(int w=2;w<=N;w++){
      for(int i=0;i+w<=N;i++){
        int j=i+w;
        int si=i+1;
        int ti=j-1;
        if(w>2){
          si=dm[t][i][j-1];
          ti=dm[t][i+1][j];
        }
        dp[t][i][j]=1e9;
        for(int k=si;k<=ti;k++){
          if(dp[t][i][j] > dp[u][i][k]+dp[u][k][j]+a[j-1]-a[k-1]){
            dp[t][i][j]=dp[u][i][k]+dp[u][k][j]+a[j-1]-a[k-1];
            dm[t][i][j]=k;
          }
        }
      }
    }
  }
  printf("%d\n",dp[K%2][0][N]);
  return 0;
}
accuracy: 1
time_ms: 380
memory_kb: 18468
final_rank: 4

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

int N,K;
int dp[2][1001][1001];
int dm[2][1001][1001];
int a[1000];

int main(){
  scanf("%d %d",&N,&K);
  for(int i=0;i<N;i++)scanf("%d",&a[i]);
  sort(a,a+N);
  fill( (int*)dp[0], (int*)dp[1], 1e9);
  int ans=1e9;
  for(int T=1;T<=K;T++){
    int t=T%2;
    int u=1-t;
    for(int i=0;i<N;i++){
      dp[0][i][i+1]=0;
      dp[1][i][i+1]=0;
    }
    for(int w=2;w<=N;w++){
      for(int i=0;i+w<=N;i++){
        int j=i+w;
        int si=i+1;
        int ti=j-1;
        if(w>2){
          si=dm[t][i][j-1];
          ti=dm[t][i+1][j];
        }
        dp[t][i][j]=1e9;
        for(int k=si;k<=ti;k++){
          if(dp[t][i][j] > dp[u][i][k]+dp[u][k][j]+a[j-1]-a[k-1]){
            dp[t][i][j]=dp[u][i][k]+dp[u][k][j]+a[j-1]-a[k-1];
            dm[t][i][j]=k;
          }
        }
      }
    }
  }
  printf("%d\n",dp[K%2][0][N]);
  return 0;
}
accuracy: 1
time_ms: 380
memory_kb: 18384
final_rank: 3

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

int N,K;
int dp[2][1001][1001];
int dm[2][1001][1001];

int a[1000];

int main(){
  scanf("%d %d",&N,&K);
  for(int i=0;i<N;i++)scanf("%d",&a[i]);
  sort(a,a+N);
  
  fill( (int*)dp[0], (int*)dp[1], 1e9);


  int ans=1e9;
  
  for(int T=1;T<=K;T++){
    int t=T%2;
    int u=1-t;

    fill( (int*)dp[t], (int*)dp[t+1], 1e9);
    for(int i=0;i<N;i++){
      dp[0][i][i+1]=0;
      dp[1][i][i+1]=0;
    }
    
    for(int w=2;w<=N;w++){
      for(int i=0;i+w<=N;i++){
        int j=i+w;
        int si=i+1;
        int ti=j-1;

        if(w>2){
          si=dm[t][i][j-1];
          ti=dm[t][i+1][j];
        }
        
        for(int k=si;k<=ti;k++){
          if(dp[t][i][j] > dp[u][i][k]+dp[u][k][j]+a[j-1]-a[k-1]){
            dp[t][i][j]=dp[u][i][k]+dp[u][k][j]+a[j-1]-a[k-1];
            dm[t][i][j]=k;
          }
        }

        if(i==0&&j==N)ans=min(ans,dp[t][i][j]);
      }
    }
  }
  printf("%d\n",ans);
  return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 18552
final_rank: 5