Uva 11300

圆桌分钱问题求解
探讨了如何通过计算每个人给旁边的人钱的方式使所有人持有相同金额,并且总操作步骤达到最少。使用了中位数距离的思想,通过一系列数学推导得出最优解。
部署运行你感兴趣的模型镜像
 题目大意:给出一个整数n 然后n个人的钱。n个人围着一个圆桌
每个人可以给旁边的人钱。最终的目的是所有人的钱一样多。数据保证可以实现。
每有一个人给别人一块钱就是步数加一 现在要最少的步数实现。
最终每个人的钱数假设为M=tot/n;
每个人开始有的钱为Ai;
Ci表示Ai-M
这个题就是中位数的距离思想 n个人逆时针标号1-n
首先用x1表示1号给n号的钱的数量
同理x2表示2号给1号的钱
那么我么可以列等式
对于每个人 i Ai-xi+xi+1=M 就是说原来有的钱减去他给钱一个的钱加上后一个给他的钱等于M
我们可以得出 x2 = M-A1+x1 =x1-C1;
             x3 = M-A2+x2 = x2-c2 =x1-c1-c2;
     .........

我们最终希望的是x1 +x2 +xn的绝对值最小 也就是说
|x1| +|x1-c1| + |x1-c1-c2| +.....+|x1-cn-1| 最小

也就是 这n个点距离x1 的距离的绝对值最小
#include<cstdio> 
#include<iostream>
#include<algorithm>
using namespace std;

const int maxn =1000001+10;

long long a[maxn],b[maxn],totle,average;

int main()
{
   int n;
   while(scanf("%d",&n)!=EOF)
   {
          totle=0;                   
          for(int i=1;i<=n;i++)
          {
            scanf("%lld",&a[i]);    
            totle+=a[i];
          }  
          
          average =totle/n;
          
          b[0]=0;
          
          for(int i=1;i<n;i++)
          b[i]=b[i-1]-a[i]+average;
          
          sort(b,b+n);
          
          long long median=b[n/2],ans=0;
         
          for(int i=0;i<n;i++)
           ans+=abs(median-b[i]);
           
           printf("%lld\n",ans);
          
          
          
                         
                             
   }
    
    
    
return 0;    
}





                

您可能感兴趣的与本文相关的镜像

Linly-Talker

Linly-Talker

AI应用

Linly-Talker是一款创新的数字人对话系统,它融合了最新的人工智能技术,包括大型语言模型(LLM)、自动语音识别(ASR)、文本到语音转换(TTS)和语音克隆技术

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值