题意:
解法:
首先肯定要对数组从小到大排序,
然后枚举一开始选谁,假设选a[st],
那么下一步要么选a[st-1],要么选a[st+1],
但是选择方式的局部最优不一定导致全局最优.
发现任何时候选出的序列一定是连续的一段,
那么可以用区间dp做:
令d[l][r]表示[l,r]全部选完的最小代价,
转移方程:
d[l][r]=min(d[l+1][r],d[l][r-1])+a[r]-a[l].
复杂度O(n^2).
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=2e3+5;
int d[maxm][maxm];
int a[maxm];
int n;
int dfs(int l,int r){
if(l==r)return 0;
if(l+1==r)return a[r]-a[l];
if(d[l][r]!=-1)return d[l][r];
int ans=min(dfs(l,r-1),dfs(l+1,r))+a[r]-a[l];
return d[l][r]=ans;
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
memset(d,-1,sizeof d);
int ans=dfs(1,n);
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
solve();
return 0;
}