6 条题解

  • 10
    @ 2021-8-27 23:02:18

    大家都知道中位数是最优解,这里给个证明。

    前置:绝对值的几何意义:a,b|a,b| 为数轴上 aa 对应点到 bb 对应点的距离。

    推论:ax+xba+b|a-x|+|x-b| \le |a+b| ,等号当且仅当 aba \leq b 时取等。(易证)

    nn 个数已经被存储在 a1ana_1 - a_n 中,并且已经排过了序。

    nn 为偶数,

    i=1naiat=i=1n/2aiat+aniat\sum_{i=1}^{n} |a_i-a_t| = \sum_{i=1}^{n/2} |a_i-a_t|+|a_{n-i}-a_t|

    i=1n/2aniai\le \sum_{i=1}^{n/2}|a_{n-i}-a_i|

    等号当且仅当 t=n/2t=n/2t=n/2+1t=n/2+1 时取得。

    易证若将 tt 往反着最优解移动(不妨设为左移至上一个点,此时 tn/2t \le n/2),由于移动方向上接着的数(都可以缩短 atat1a_t-a_{t-1} 的路程)小于移动方向反面的数(都可以增加 atat1a_t-a_{t-1} 的路程),这种取法一定不会比当前更优。

    最优性得证。

    nn 为奇数基本一致,只是配对部分省去中间一个数再前后配对,易证此时最优的 t=(n+1)/2t=(n+1)/2

    综上,t=(n+1)/2t=\lfloor (n+1)/2 \rfloor 为最优解。

    • @ 2021-8-27 23:07:03

      还好公式没炸……调了好久

    • @ 2022-8-6 19:53:22

      @ 这个求和符号怎么

  • 5
    @ 2023-8-21 14:02:29

    题目描述

    在一条直线道路上有多个住户,现在想在这条直线道路上开一家超市,超市可以开在任何位置,包括住户所在的位置。现在请你编程求解,超市开在哪里,可以使所有住户到商店的距离的总和是最小的。

    看完感受:把超市开在住户家里,也太邪恶人性化了。

    言归正传,题目背景摆明了本题考查贪心思想

    证明贪心策略比较简单,在升序排列中第 (n+1)>>1 项。

    距离公式为 |a-b| (求a,b两地间的距离)

    代码如下:

    #include <iostream>
    #include <algorithm>
    using namespace std;
    int a[100005],n,sum;
    int main()
    {
        cin >> n;
        for(int i=1;i<=n;i++)
        {
            cin >> a[i];
        }
        sort(a+1,a+n+1);
        int x=a[(n+1)>>1];
        for (int i=1;i<=n;i++)
        {
            sum+=abs(x-a[i]);//这里就是上文提到的距离公式
        }
        cout << sum;
        return 0;
    }
    
    • 0
      @ 2022-8-22 10:18:02
      sort(a+1,a+n+1);
      for (int i=1;i<=n;i++)
      {
          ans+=abs(a[(n+1)/2]-a[i]);
      }
      cout<<ans;
      
      • -2
        @ 2023-2-11 15:27:54
        #include <bits/stdc++.h>
        using namespace std;
        int a[100001];//注意了
        int main(){   
            int n,mid=0,ans=0;
            cin>>n;
            for(int i=1;i<=n;i++)
                cin>>a[i];
            sort(a+1,a+n+1);
            if(n%2==0){
                mid=a[n/2];//详情请看梓璇
            }else{
                mid=a[(n+1)/2];
            }
            for(int i=1;i<=n;i++){
                ans+=abs(mid-a[i]);//学过初一上学期的绝对值的人都知道
            }cout<<ans;
            return 0;
        }//不对出来打我
        
        
        </span>
        • -3
          @ 2022-4-24 16:12:46

          鼓励大家写题解,但注意题解格式。

          给代码两端加上这个会舒服一些

          ```cpp

          你的代码

          ```

          </span>

          这个点在键盘的左上角tab上面那个键,注意切换输入法

          #include<iostream>
          using namespace std;
          int main()
          {
              int n;
              cin>>n;//这是一个注释
              return 0;
          } 
          

          请注意严禁抄袭题解,写题解不要只放代码,需加上你的思路或代码注释。

          抄袭题解一经发现直接取消成绩。

          • -5
            @ 2021-8-27 22:05:11

            排序挺费时间的。二分更快更电脑。

            • 1

            信息

            ID
            1231
            时间
            1000ms
            内存
            256MiB
            难度
            6
            标签
            递交数
            938
            已通过
            273
            上传者