题目地址:http://codeforces.com/problemset/problem/433/C
这题实在没什么思路,思路是从网上看的。智商不能暴露太多。。。
这题的思路是把每一个数的与之相邻的保存下来,为了方便,可以用vector数组。然后为了使得距离之和最短,要取中位数。在一串数字中,距所有数字距离之和最短的就是中位数了,这点应该很好理解。然后把该值修改为该中位数,然后最后找出能使值减少的最大的就是最终要修改的值。
代码如下:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
#define LL __int64
vector<int>q[110000];
int a[110000];
int main()
{
int n, m, i, max1=-1, len, x, j;
LL tmp, sum=0, min1;
scanf("%d%d",&n,&m);
for(i=0; i<m; i++)
{
scanf("%d",&a[i]);
if(i!=0&&a[i]!=a[i-1])
{
sum+=abs(a[i]-a[i-1]);
q[a[i]].push_back(a[i-1]);
q[a[i-1]].push_back(a[i]);
}
if(max1<a[i])
max1=a[i];
}
min1=sum;
for(i=1;i<=max1;i++)
{
tmp=sum;
int len=q[i].size();
if(len==0)
continue ;
sort(q[i].begin(),q[i].end());
x=q[i][len/2];
for(j=0;j<len;j++)
{
tmp+=abs(x-q[i][j])-abs(i-q[i][j]);
}
min1=min(tmp,min1);
}
printf("%I64d\n",min1);
return 0;
}