codeforces433c

给你一个数组,这个数组大小为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 }
View Code

猜你喜欢

转载自www.cnblogs.com/pandaking/p/10454134.html