• 第五届华中区程序设计邀请赛暨武汉大学第十四届校赛 网络预选赛 A Minimum Sum 树状数组


    Problem 1603 - Minimum Sum
     
    Description

    There are n numbers A[1] , A[2] .... A[n], you can select m numbers of it A[B[1]] , A[B[2]] ... A[B[m]]  ( 1 <= B[1] < B[2] .... B[m] <= n ) such that Sum as small as possible.

    Sum is sum of abs( A[B[i]]-A[B[j]] ) when 1 <= i < j <= m.

    Input
    There are multiple test cases.
    First line of each case contains two integers n and m.( 1 <= m <= n <= 100000 )
    Next line contains n integers A[1] , A[2] .... A[n].( 0 <= A[i] <= 100000 )
    It's guaranteed that the sum of n is not larger than 1000000.
    Output
    For each test case, output minimum Sum in a line.
    Sample Input
    4 2
    5 1 7 10
    5 3
    1 8 6 3 10
    Sample Output
    2
    8
     
    题意:
     
      给你n个数,让你选M个数来,使得 sigma abs( A[B[i]]-A[B[j]] ) when 1 <= i < j <= m.最小
     
    题解:
        
        排序过后,就是选择连续的m个数了
      由于数的范围小,我们在统计连续和的时候 利用BIT优化
     
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    using namespace std;
    const int N = 1e5+10, M = 50, mod = 1e9+9, inf = 1e9+9;
    typedef long long ll;
    
    ll sum;
    
    int n,m,a[N];
      int C[N],A[N];
        int lowbit(int x) {
            return x&(-x);
        }
        void add(int x, int add) {
            for (; x < N; x += lowbit(x)) {
                C[x] += add;
            }
        }
        int sums(int x) {
            int s = 0;
            for (; x > 0; x -= lowbit(x)) {
              s+=C[x];
            }
            return s;
        }
    int main() {
        while(scanf("%d%d",&n,&m)!=EOF) {
                memset(C,0,sizeof(C));
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            sort(a+1,a+n+1);
            sum = 0;
            for(int i=1;i<=m;i++) {
                sum+=(a[i]*(i-1)-sums(i));
                add(i,a[i]);
            }
      // cout<<sum<<endl;
            ll ans = sum;
            for(int i=m+1;i<=n;i++) {
                sum -= (sums(i)-sums(i-m)-a[i-m]*(m-1));
              // cout<<(sums(i)-sums(i-m+1)-a[i-m]*(m-1))<<endl;
              //  cout<<sum<<endl;
                sum += (a[i]*(m-1)-sums(i)+sums(i-m));
                add(i,a[i]);
                ans = min(ans,sum);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
      
  • 相关阅读:
    [探索][管理]《现在,发现你的优势》
    【成功智慧】010.依靠忍耐度过困难时期
    爱情五十九课,就差一句话
    VSS2005 托管 VS2010代码
    一个网站的金字塔战略
    【成功智慧】013.脚踏实地的去做,没有完不成的任务
    MU.Bread 麦卡优娜
    【成功智慧】012.要有耐心去等待成功的到来
    【成功智慧】009.要能够承受所发生的事情
    【成功智慧】014.一日复一日的度过难关
  • 原文地址:https://www.cnblogs.com/zxhl/p/5372325.html
Copyright © 2020-2023  润新知