环形数组优美可以有两种方式:一种是前面i-2个数可以组成优美的环形数组,让第i个和第i-2个数变相同;还有一种是前面i-3个数可以组成优美的环形数组,让第i-2个、第i-1个和第i个数变相同。
那要变相同的数怎么加减次数最少呢?往他们中位数的方向去变。记录最大值maxx和最小值minn,最少的加减次数为maxx-minn。
AC代码:
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=400005;
int t,n,dp[maxn],a[maxn],ans;
signed main(){
cin>>t;
while(t--){
cin>>n;
ans=1e18;
for(int i=1;i<=n;i++) {
cin>>a[i];
a[i+n]=a[i];
}
for(int i=0;i<3;i++){
for(int j=1;j<=n*2;j++) dp[j]=1e18;
dp[i]=0;
for(int j=i+1;j<=i+n;j++){
if(j>=2) dp[j]=min(dp[j],dp[j-2]+abs(a[j]-a[j-1]));
if(j>=3){
int maxx=0,minn=1e18;
for(int k=j-2;k<=j;k++){
maxx=max(maxx,a[k]);
minn=min(minn,a[k]);
}
dp[j]=min(dp[j],dp[j-3]+maxx-minn);
}
}
ans=min(ans,dp[n+i]);
}
cout<<ans<<endl;
}
return 0;
}