UVa 11300 Spreading the Wealth (数学推导-中位数)
2016-12-07 21:53
417 查看
UVa 11300 Spreading the Wealth
题目大意:
n个人围成环形,一个人可以给他相邻左右两边的人金币,求使得所有人最后的金币数相同的最少转手金币数,金币总数能被n整除.题目分析:
这是一个环形的结构,可以尝试将其变成单向的,Xi表示从i传到i+1的金币个数(Xn表示从n传到1的金币个数),设每人最终的金币个数为M,则有Ai+Xi−1−Xi=M.设Ci=∑ni=1(Ai−M),则有
对于第1个人,A1+Xn−X1=M→X1=Xn−C1
对于第2个人,A2+X1−X2=M→X2=Xn−C2
…
对于第n个人,An+Xn−1−Xn=M.然而这个式子却没有用,可以由前面n-1的式子推导得到,所以需要挖掘其他的信息.
由上述推导可知
ans=min{|Xn|+|Xn−C1|+...+|Xn−Cn−1|}
实际上当Xn为C序列的中位数,有最小值.
原因在于,如果将Xn变成Xn+1,则有
ans′=ans+left−right
(left/right表示小于等于/大于Xn的C的个数),
要使ans最小,则应当使得当前小于/大于Xn相同,所以Xn为C序列中位数
代码:
#include<cmath> #include<cstdio> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int maxn=1000000+10; ll A[maxn],C[maxn]; int main() { int n; while(scanf("%d",&n)==1) { ll sum=0; for(int i=1;i<=n;i++) scanf("%lld",&A[i]),sum+=A[i]; ll M=sum/n; for(int i=1;i<=n;i++) C[i]=C[i-1]+M-A[i];//求出C序列的值 sort(C+1,C+n+1); ll x=C[n>>1],ans=0;//X为排序后C数组的中间值 for(int i=1;i<=n;i++) ans+=abs(x-C[i]); printf("%lld\n",ans); } return 0; }
相关文章推荐
- UVA 11300 - Spreading the Wealth(数学推导+中位数)
- UVA 11300 Spreading the Wealth (数学推导 中位数)
- UVa Spreading the Wealth-11300(数学推导+中位数)
- UVA11300 Spreading the Wealth (数学推导+中位数)
- uva - 11300 - Spreading the Wealth(数学推导,中位数)
- UVa - 11300 - Spreading the Wealth ( 数学推导 )
- Uva 11300 Spreading the Wealth(数学,中位数)
- UVA 11300 Spreading the Wealth (数学推导)
- Spreading the Wealth UVA - 11300 找规律+数学推导
- uva11300 - Spreading the Wealth (中位数)
- UVa 11300 Spreading the Wealth 分金币 (中位数)
- UVa11300 Spreading the Wealth(数学问题)
- UVa-11300 - Spreading the Wealth(中位数)
- 中位数-分金币(Spreading the Wealth, UVa 11300)
- UVa 11300 Spreading the Wealth——中位数
- Uva 11300 Spreading the Wealth (代数分析 + 中位数)
- UVA 11300 Spreading the Wealth 中位数 *
- UVA.11300 Spreading the Wealth (思维题 中位数模型)
- UVA 11300 Spreading the Wealth(数学)
- UVA 11300 SPREADING THE WEALTH 【数学】