uva11300(抽象,推导)

题目的数据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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值