给你一个数组,这个数组大小为m,这些数字的大小都不超过n,然后你可以改变这个数组里面的一些值相同的数字,而且必须同时把全部数字相同的改掉,求改动后abs(a[2]-a[1])+abs(a[3]-a[2])+....+abs(a[n]-a[n-1])的最小值
首先我们可以知道,要怎么想呢,我们改变某个数之后的变化量是啥,那肯定是和他旁边的这些数,我把这些数都用一个vector存起来,发现一个性质,我怎么才能让变化后的数变小,显然我们肯定是要取中位数,然后枚举一下这道题就做完了
接下来是代码:
1 #include <iostream> 2 #include <algorithm> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstring> 6 #include <vector> 7 using namespace std; 8 const int maxn=100100; 9 typedef long long ll; 10 ll res=0,ans=0,mx=0,mi; 11 int n,m; 12 ll num[maxn]; 13 vector<ll> G[maxn]; 14 int main(){ 15 scanf("%d%d",&m,&n); 16 for(int i=1;i<=n;i++) scanf("%lld",&num[i]); 17 mx=num[1];mi=num[1]; 18 for(int i=2;i<=n;i++){ 19 mx=max(mx,num[i]); 20 mi=min(mi,num[i]); 21 if(num[i]!=num[i-1]){ 22 G[num[i]].push_back(num[i-1]); 23 G[num[i-1]].push_back(num[i]); 24 } 25 res+=abs(num[i]-num[i-1]); 26 } 27 ans=res; 28 for(ll i=mi;i<=mx;i++){ 29 ll t=res; 30 int sz=G[i].size(); 31 if(sz==0) continue; 32 sort(G[i].begin(),G[i].end()); 33 ll s=G[i][sz/2]; 34 for(int j=0;j<sz;j++) t+=(abs(s-G[i][j])-abs(i-G[i][j])); 35 ans=min(ans,t); 36 } 37 printf("%lld\n",ans); 38 return 0; 39 }