\(\huge\mathbb{DESCRIPTION}\)
编号:洛谷\(P4016\)、\(LOJ6013\)(与洛谷上本题完全相同)
算法:最小费用最大流\(\mathbb{OR}\)贪心
来源:网络流\(24\)题
\(\huge\mathbb{SOLUTION}\)
这道题目我们可以用最小费用最大流来解决。
但是,我觉得贪心也可以啊。
这明明就是均分纸牌...
考虑一下怎么贪心。
首先,不难想到,我们要先求出平均数。
要想求平均数,就要求和。
易知:
\[Sum=\sum_{i=1}^N Array_i \]
\[Average=\frac{Sum}{N} \]
然后,我们不妨把\(Array_i\)减去\(Sum\)。
这样\(Array_i\)就变成了与目标的差。
最后,我们按开始的序列顺序,像普通均分纸牌一样处理出前缀和\(Prefix\)数组,那么假设枚举的位置为\(x\),则类比普通均分纸牌求法,新的\(Prefix_i=Prefix_i-Prefix_x\),于是:
\[Answer=\sum{|Prefix_i-Prefix_x|} \]
易证\(Prefix_x\)为\(Prefix\)数组的中位数时,\(Ans\)最小。
于是就解决了。
\(\huge\mathbb{CODE}\)
#include<bits/stdc++.h>
using namespace std;
int N;
long long Array[101],Prefix[101];
int main(void)
{
register int i;
cin>>N;
for(i=1;i<=N;i++)
{
cin>>Array[i];
}
register long long Sum;
Sum=0;
for(i=1;i<=N;i++)
{
Sum+=Array[i];
}
Sum/=N;
for(i=1;i<=N;i++)
{
Array[i]-=Sum;
Prefix[i]=Prefix[i-1]+Array[i];
}
sort(Prefix+1,Prefix+N+1);
Sum=0;
for(i=1;i<=N;i++)
{
Sum+=abs(Prefix[N/2+1]-Prefix[i]);
}
cout<<Sum<<endl;
return 0;
}