笔记

 

 

【题目分析】

  用动态数组存储下与i相邻的数字,然后枚举每一个i的改变,那什么时候能让i值改变得到的代价减小值最大呢,当然要找到与i相连的那些数字的中位数。 (可以手推一下)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define ll long long
const int maxn=100010;
vector<int>b[maxn];
int n,m;

int a[maxn];
ll ans=0,sum1,sum2,sum=0;
int Abs(int x)
{
    return x<0?-x:x;
}
int main()
{
    freopen("note.in","r",stdin);
    freopen("note.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&a[i]);
        if(i>1)
            ans+=Abs(a[i]-a[i-1]);
    }
    for(int i=1;i<=m;i++)//把与a[i]相邻的数字添到b[a[i]]中 
    {
        if(i>1&&a[i-1]!=a[i]) b[a[i-1]].push_back(a[i]);//只有两数不相等时猜对答案有贡献 
        if(i<m&&a[i+1]!=a[i]) b[a[i+1]].push_back(a[i]);//
    }
    for(int i=1;i<=n;i++)
    {
        if(b[i].size()==0) continue;
        sort(b[i].begin(),b[i].end());
        int y=b[i][b[i].size()>>1];//这里需要好好理解 
        sum1=0;sum2=0;
        for(int j=0;j<b[i].size();j++)
        {
            sum1+=Abs(i-b[i][j]);
            sum2+=Abs(y-b[i][j]);
        }
        sum=max(sum,sum1-sum2);//找出最大的改变这个i的所能减小的代价 
    }
    ans-=sum;
    cout<<ans;
    fclose(stdin);fclose(stdout);
    return 0;
}

 

posted @ 2016-11-13 18:40  [lemon]  阅读(154)  评论(0编辑  收藏  举报
……