zoukankan      html  css  js  c++  java
  • 数学

    Problem's Link

    mean

    给定n个整数,从中选出m个整数出来,使得这m个整数两两求(差的绝对值),并保证(差的绝对值)之和最小。

    analyse

    首先,要使得m个数(差的绝对值)之和最小,易知这m个数应该是连续的,所以先排序。

    然后就是滑窗法了。

    滑的时候如何维护滑块的sum呢?

    如果我们选出的数是:

      a1 a2 ... ak

    对于a1,后面有k-1个数,且每个数都是减去它,即:a1带了k-1次负号;

    对于a2,后面有k-2个数,且每个数都是减去它,,带了k-2次负号,但是他还要减去它前面的所有数,又带了k-1次正号,相抵后总的带了k-3次负号;

    对于a3,后面有k-3个数,且每个数都是减去它,,带了k-3次负号,但是他还要减去它前面的所有数,又带了k-2次正号,相抵后总的带了k-5次负号;

    ...

    由此可以看出,求m个数(差的绝对值)之和的方式是:

      sum1 = a1*(1-k) + a2*(3-k) + a3*(5-k) + ... + ak*(k-1)

    向后滑动一个数,sum2的求法一样,这时我们来对比一下sum1和sum2的差别:

      sum1 = a1*(1-k) + a2*(3-k) + a3*(5-k) + ... + ak*(k-1)

      sum2 =            a2*(1-k) + a3*(3-k) + ... + ak*(k-3) + a(k+1)*(k-1)

    我们先预处理出s[]数组,s[i]代表a0~ai的和.

    那么:sum2=sum1+ai*(k-1)-a(i-k)*(1-k)-2*(s[i-1]-s[i-k]).

    time complexity

    O(N)

    view code

     

    #include <bits/stdc++.h>
    using namespace std;
    const int N=100010;
    
    int a[N],s[N];
    int main()
    {
       freopen("G:\nowcoder\in","r",stdin);
       freopen("G:\nowcoder\out","w",stdout);
       int n,k,T;
       scanf("%d",&T);
       while(T--)
       {
           scanf("%d %d",&n,&k);
           for(int i=0; i<n; ++i)
               scanf("%d",&a[i]);
           sort(a,a+n);
           s[0]=a[0];
           for(int i=1; i<n; ++i)
               s[i]=s[i-1]+a[i];
           long long sum=0,cnt=1-k;
           for(int i=0; i<k; ++i)
           {
               sum+=a[i]*cnt;
               cnt+=2;
           }
           long long res=sum,l=0;
           for(int i=k; i<n; ++i)
           {
               sum-=a[l]*(1-k);
               sum+=a[i]*(k-1);
               sum-=2*(s[i-1]-s[l]);
               res=min(res,sum);
               ++l;
           }
           printf("%lld
    ",res);
       }
       return 0;
    }

     

  • 相关阅读:
    Java实现 LeetCode 524 通过删除字母匹配到字典里最长单词(又是一道语文题)
    dmalloc arm-linux平台使用
    dmalloc在嵌入式的开发板上的应用
    利用linux的mtrace命令定位内存泄露(Memory Leak)
    Linux C 编程内存泄露检测工具(一):mtrace
    Ubuntu10.04下安装Qt4和创建第一个Qt程序
    UBuntu14.04下安装和卸载Qt5.3.1
    MinGW 与MSVC的区别
    Qt5 编译 & 打包依赖dll发布
    查看gcc/g++默认include路径
  • 原文地址:https://www.cnblogs.com/crazyacking/p/5376337.html
Copyright © 2011-2022 走看看