• 数学


    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;
    }

     

  • 相关阅读:
    Python使用QRCode模块生成二维码
    C++ STL中允许重复key的multimap
    C++ STL中Map的按Value排序
    C++ STL中Map的按Key排序
    C++ String和其他类型互换
    android studio
    加快android studio 编译速度(已更新至Android Studio 3.3.1)
    解决Installation failed with message Failed to finalize session : INSTALL_FAILED_INVALID_APK的问题
    Android 自定义Dialog 去除阴影
    FFmpeg(14)-使用NDK、C++完成EGL,display, surface, context的配置和初始化
  • 原文地址:https://www.cnblogs.com/crazyacking/p/5376337.html
Copyright © 2020-2023  润新知