标签:最小化 char abs 不可 har main mes names return
环形均分纸牌问题
考虑环形纸牌问题,相当于从环中某点\(k\)断开求一边基本均分纸牌问题
每个人达到平均值所用步数分别为\(res_{k+1}-res_k,res_{k+2}-res_k,\dots,res_{n}-res_k,res_1+res_n-res_k,\dots,res_k+res_n-res_k\)
由于\(res_n=0\)所以\(ans=\sum_{i=1}^n\left| res_i-res_k\right|\)
我们的最终目标是使\(ans\)最小化。
绝对值相当于数轴上数的距离,相当于我们找一个点\(k\),使得它到数轴上其他点的距离之和最小,这是经典的中位数问题,中位数到数轴上其他点的距离之和最小,因此我们选\(res_i\)的中位数即可。当\(n\)为奇数时,选\(res_{\frac{k}{2}+1}\),当\(n\)为偶数时选\(res_{\frac{k}{2}}\)或\(res_{\frac{k}{2}+1}\)都可以。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
int x=0,f=1;char ch=‘ ‘;
while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘) f=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+(ch^‘0‘);ch=getchar();}
return x*f;
}
const int N = 1000000 + 10;
typedef long long ll;
int a[N];
ll s,sum[N];
int main(){
// freopen("data.in","r",stdin);
// freopen("sol.out","w",stdout);
int n;n=read();
int ave;
for(int i=1;i<=n;i++) {
a[i]=read();s+=a[i];
}
ave=s/n;
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]-ave;
sort(sum+1,sum+n+1);
int mid=sum[n/2+1];
long long ans=0;
for(int i=1;i<=n;i++){
ans+=abs(sum[i]-mid);
}
printf("%lld",ans);
return 0;
}
P2512 [HAOI2008]糖果传递 - 贪心+中位数【环形均分纸牌问题】
标签:最小化 char abs 不可 har main mes names return
原文地址:https://www.cnblogs.com/Loi-Brilliant/p/9785046.html