【题目分析】
用动态数组存储下与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; }