传送门
题意:你可以这个两种操作(1.将数组后缀的所有元素增加1。2.将数组后缀的所有元素减少1。)
将数组元素全部变成一个相同的值,问最少操作次数。在执行操作之前可以任意改变
一个元素的值
分析: 我们可以先不修改元素,直接算总的操作次数sum,然后可以枚举每一个元素删去,
维护最小值sum即可
例如:a1 a2 a3 a4 a5
假设删去a3,那可sum的值就变成了:sum-[abs(a2-a3)+abs(a3-a4)]+abs(a2-a4);
最后对于两个端点分类讨论即可
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <bitset>
#include <vector>
#include<cstring>
#include <stdio.h>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
inline int read(){int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}
const int maxn = 2e5+5;
ll a[maxn];
int main()
{
int t=read();
while (t--)
{
int n=read();
bool flag=true;
cin>>a[1];
for(int i=2;i<=n;i++)
{
cin>>a[i];
if(a[i]!=a[i-1]) flag=false;
}
if(flag||n==2){puts("0");continue;}
ll sum=0;
for(int i=n;i>=2;i--)
sum+=abs(a[i-1]-a[i]);
ll Min=sum;
for(int i=1;i<=n;i++)
{
if(i==1)
{
Min=min(Min,sum-abs(a[i]-a[i+1]));
Min=min(Min,sum-abs(a[i+1]-a[i+2])+abs(a[1]-a[3]));
}
else if(i==n)
{
Min=min(sum-abs(a[n-1]-a[n]),Min);
Min=min(Min,sum-abs(a[n-2]-a[n-1])+abs(a[n-2]-a[n]));
}
else{
ll x=abs(a[i-1]-a[i+1]);
ll y=abs(a[i]-a[i+1])+abs(a[i-1]-a[i]);
Min=min(sum-y+x,Min);
}
}
printf("%lld\n",Min);
}
return 0;
}