​|–>题目传送门<–|​

题目描述

学生会正在为体育节的接力赛做准备。学生会由 n个成员组成,他们将在比赛中一个一个地跑,第 NamoCamp 每日一题 体育节 区间DP_算法 个人的速度是 NamoCamp 每日一题 体育节 区间DP_最小值_02,第 i次接力会产生一个差异值 NamoCamp 每日一题 体育节 区间DP_c++_03,它的值是前 NamoCamp 每日一题 体育节 区间DP_算法个参与接力赛的人的速度最大值与最小值的差,也就是说,我们假设第NamoCamp 每日一题 体育节 区间DP_算法个参与比赛的人的速度是 NamoCamp 每日一题 体育节 区间DP_c++_06,那么 NamoCamp 每日一题 体育节 区间DP_算法_07。现在你可以任意安排参加比赛的人的顺序,一个人只能参与一次,且每个人都必须参与,请你求出NamoCamp 每日一题 体育节 区间DP_最小值_08的最小值。

题解

首先考虑插入数字NamoCamp 每日一题 体育节 区间DP_最小值_09的影响:

  • 如果NamoCamp 每日一题 体育节 区间DP_算法_10是区间NamoCamp 每日一题 体育节 区间DP_i++_11,那么新增NamoCamp 每日一题 体育节 区间DP_c++_12
  • 如果NamoCamp 每日一题 体育节 区间DP_算法_10是区间NamoCamp 每日一题 体育节 区间DP_最小值_14,那么新增NamoCamp 每日一题 体育节 区间DP_#define_15
  • 如果都不是,那么新增NamoCamp 每日一题 体育节 区间DP_i++_16

那么显然,每插入一个区间最大值,新增极差的大小都会NamoCamp 每日一题 体育节 区间DP_#define_17,从贪心的角度考虑,我们应当尽可能晚的插入区间最大值。所以我们可以先对所有的NamoCamp 每日一题 体育节 区间DP_c++_06排序。

NamoCamp 每日一题 体育节 区间DP_#define_19表示区间NamoCamp 每日一题 体育节 区间DP_c++_20的答案(和的最小值)。

考虑一段区间NamoCamp 每日一题 体育节 区间DP_#define_21的状态:显然可以由(NamoCamp 每日一题 体育节 区间DP_i++_22表示NamoCamp 每日一题 体育节 区间DP_c++_23的贡献):

  1. NamoCamp 每日一题 体育节 区间DP_#define_24
  2. NamoCamp 每日一题 体育节 区间DP_算法_25

两个状态转移而来。同时由于我们对整个序列进行过排序,那么可以得知:
NamoCamp 每日一题 体育节 区间DP_#define_26

那么可以直接跑一个区间NamoCamp 每日一题 体育节 区间DP_i++_27,计算答案即可。

#include <bits/stdc++.h>
#define int long long


const int N = 2e3 + 10;
int a[N], dp[N][N];

inline bool cmp(const int &a, const int &b){ return a < b; }

inline void solve(){
int n = 0; std::cin >> n;
for(register int i = 1; i <= n; i++) std::cin >> a[i];
std::sort(a + 1, a + 1 + n, cmp);
for(int len = 2; len <= n; len++){
for(int l = 1; l <= n; l++){
int r = l + len - 1;
if(r > n) continue;
dp[l][r] = (a[r] - a[l]) + std::min(dp[l + 1][r], dp[l][r - 1]);
}
}
std::cout << dp[1][n] << std::endl;
}

signed main(){
solve();
return 0;
}