2 条题解

  • 0
    @ 2025-10-8 17:01:43

    设最优的方案中,位置1往位置n送k捆草,则: a[2]要往a[1]移s[1]捆,s[1]=b[1]-(a[1]-k)=b[1]-a[1]+k; a[3]要往a[2]移s[2]捆,s[2]=b[2]-(a[2]-(b[1]-a[1]+k))=(b[2]-a[2]) + (b[1]-a[1]) +k个, 以此类推...... a[i+1]要往a[i]移s[i]捆,s[i]=Σ(b[j]-a[j])(1<=j<i)+ k ; 设 c[i]=(b[1]-a[1])+(b[2]-a[2])+.....+(b[i]-a[i]) 故: s[1]=c[1]+k s[2]=c[2]+k ... s[i]=c[i]+k 注 s[i]和 k 的值可正可负,才能表达 某个位置可向左右送草。 答案为:Σ|s[i]|=Σ|c[i]+k| c[i]是确定的,k不是确定的,如何设计k的值让Σ|c[i]+k|最小? 可以将|c[i]+k|转化为|c[i]-(-k)|,则答案可以看成一条数轴上,值为c[i](1<=i<=n)的点到(-k)的距离。 所以:当k为其中位数时,答案最小

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int a[N],b[N],c[N];
    int main()
    {
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]);
        c[0]=0;
        for(int i=1;i<=n;i++)
        {
            c[i]=c[i-1]+b[i]-a[i];
        }
        sort(c+1,c+n+1);
        int k=c[(n+1)/2];
        long long ans=0;
        for(int i=1;i<=n;i++) ans+=abs(c[i]-k);
        printf("%lld\n",ans);
        return 0;   
    }
    
    • 0
      @ 2025-10-8 17:01:33
      /*
      设最优的方案中,位置1往位置n送k捆草,则:
      a[2]要往a[1]移s[1]捆,s[1]=b[1]-(a[1]-k)=b[1]-a[1]+k;
      a[3]要往a[2]移s[2]捆,s[2]=b[2]-(a[2]-(b[1]-a[1]+k))=(b[2]-a[2]) + (b[1]-a[1]) +k个,
      以此类推......
      a[i+1]要往a[i]移s[i]捆,s[i]=Σ(b[j]-a[j])(1<=j<i)+ k ;
      设 c[i]=(b[1]-a[1])+(b[2]-a[2])+.....+(b[i]-a[i])
      故:
      s[1]=c[1]+k
      s[2]=c[2]+k
      ...
      s[i]=c[i]+k
      注 s[i]和 k 的值可正可负,才能表达 某个位置可向左右送草。
      答案为:Σ|s[i]|=Σ|c[i]+k|
      c[i]是确定的,k不是确定的,如何设计k的值让Σ|c[i]+k|最小?
      可以将|c[i]+k|转化为|c[i]-(-k)|,则答案可以看成一条数轴上,值为c[i](1<=i<=n)的点到(-k)的距离。
      所以:当k为其中位数时,答案最小。
      */
      #include<bits/stdc++.h>
      using namespace std;
      const int N=1e5+10;
      int a[N],b[N],c[N];
      int main()
      {
          int n;scanf("%d",&n);
          for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]);
          c[0]=0;
          for(int i=1;i<=n;i++)
          {
              c[i]=c[i-1]+b[i]-a[i];
          }
          sort(c+1,c+n+1);
          int k=c[(n+1)/2];
          long long ans=0;
          for(int i=1;i<=n;i++) ans+=abs(c[i]-k);
          printf("%lld\n",ans);
          return 0;   
      }
      • 1

      *【中位数】环上移动干草[USACO12MAR] Haybale Restacking G

      信息

      ID
      2615
      时间
      1000ms
      内存
      128MiB
      难度
      4
      标签
      递交数
      67
      已通过
      33
      上传者