题目的数据n很大,所以如果直接模拟,或者暴力搜索都是不太可能的。
直观上问题的表象很复杂,抽象就是一种强大的方法。
诸如此类的问题应该如何考虑呢。
首先,通过样例尝试找到某些不变性和等效性。而这些性质是算法产生优化的基础。
之后要进行数学抽象,转化成已解决的问题,或者自己推导到可以解决的地步,并记住这个方法。
如果设出转移量,那么一个人只需考虑他旁边的两个转移,n个人的转移变量数为n个,尝试通过变换转化为极值问题。
设最终金币数量M,初始为Ai,向下移位转移量设为Xi。
A1-X1+Xn=M
A2-X2+X1=M
A3-X3+X2=M
.....................
X2=A2-M+X1
X3=A3-M+X2=A3+A2-2M+X1
..............
所以每个xi都可以用一个来表示
那么使xi和最小就是求
x1+|x1-c1|+|x1-c2|+|x1-c3|+|x1-c4|---最小值
以上为代数过程,在几何意义上就是中位数
#include <bits/stdc++.h>
using namespace std;
long long c[1000002];
int n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
int i;
long long sum=0;
for(i=0;i<n;i++)
{
scanf("%lld",&c[i]);
sum+=c[i];
}
long long m=sum/n;
c[0]=c[0]-m;
for(i=0;i<n-1;i++)
{
c[i+1]=c[i]-m+c[i+1];
}
c[i]=0;
sort(c,c+n);
long long x1=c[n/2];
long long ans=0;
for(i=0;i<n;i++)
{
ans+=abs(x1-c[i]);
}
printf("%lld\n",ans);
}
return 0;
}