B. Suffix Operations(思维)

传送门

题意:你可以这个两种操作(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;
}
上一篇:判断该文件是否是Excel文档


下一篇:codeforces 1453 B - Suffix Operations(构造、思维)