2019牛客寒假算法基础集训营1B

题目链接

https://ac.nowcoder.com/acm/contest/317/B

题意

给定一个只有 0 0 2 2 4 4 的数字序列,你可以任意排序,现在让你求 i = 1 n ( a i a i 1 ) 2 \sum^{n}_{i=1}(a_i-a_{i-1})^2 的最大值,默认 a 0 = 0 a_0=0

思路

输入的序列其实用处不大,因为最终不需要输出方案,我们只需要记录下 2 2 / 0 0 / 4 4 分别岀现的次数即可

  • 一个显然的构造策略是首先放置 4 , 0 , 4 , 0 4, 0, 4, 0 ,直到其中一个用光。
  • 接下来如果 4 4 多余,那么可以按 4 , 0 , 4 , 0 , 4 , 2 , 4 , 2 4,0,4,0,…,4,2,4,2 ,…(先 4 4 2 2 )的方法构造。
  • 如果 0 0 多余,可以按照 4 , 0 , 4 , 0 4 , 0 , 2 , 0 , 2 4,0,4,0…4,0,2,0,2 …(先 2 2 0 0 )的方法构造。

实际上此题我们可以推广到更一般的情况,也就是第一个位置放最大的,第二个位置放最小的,第三个位置放第二大的以此类推,这种思路写起来也会更简单一些。

参考代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 4e6;
const int INF = 1e8, mod = 1e7 + 7;
using namespace std;
int a[N], ans[N], n;
int main() {
  while (~scanf("%d", &n)) {
    ll sum = 0;
    for (int i = 1; i <= n; i++) {
      scanf("%d", &a[i]);
    }
    sort(a + 1, a + n + 1);
    int l = 1, r = n;
    for (int i = 1; i <= n; i++) {
      if (i & 1) {
        ans[i] = a[r--];
      } else {
        ans[i] = a[l++];
      }
      sum += (ans[i] - ans[i - 1]) * (ans[i] - ans[i - 1]);
    }
    printf("%lld\n", sum);
  }
  return 0;
}
发布了311 篇原创文章 · 获赞 226 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/nuoyanli/article/details/104125682