📌  相关文章
📜  国际空间研究组织 | ISRO CS 2015 |问题2(1)

📅  最后修改于: 2023-12-03 15:23:03.950000             🧑  作者: Mango

国际空间研究组织 | ISRO CS 2015 |问题2

题目描述

给定一个长度为N的整数序列A。你需要选取一个区间[L, R](1 ≤ L ≤ R ≤ N)并对其进行重排,使得重新排列后的序列B满足 |B1−B2|+|B2−B3|+...+|BN−1−BN| 最小。其中|X|代表X的绝对值。

输入格式

第一行包含一个整数N。 第二行包含N个整数A1,A2,..AN。

输出格式

输出一个整数,代表最小的总和。

数据范围

对于30%的数据,1≤N≤1000 对于100%的数据,1≤N≤100000,1≤Ai≤1000

示例

输入

4
3 2 4 1

输出

5
题解

这道题是一个找规律的题,不需要什么算法知识,可以举个例子找规律: 对于序列 a1, a2, a3, ... an,我们将其排序后得到 b1, b2, b3, ... bn 则对于 k 非等于 1 和 n 的情况,重排后的序列 b1, b2, ... bk-1, bk, bn, bk+1, ... bn-1 计算 |b1-b2|+|b2-b3|+...+|bn-1-bn| 的值: 等于 (bk-1-a1)+(a2-bk-1)+(a3-bk)+(bk+1-a4)+(a5-bk+1)+...+(an-bn-1)

设 sum = (a1-a2)+(a3-a4)+...+(an-1-an), 则 sum - 2a2 + 2a3 + 2bn - 2bn-1 因为 bun在计算过程中出发了两次,所以 2bn-2bn-1

最终的结果是 sum - 2a2 + 2a3 + 2b(n-1) - 2bn

回到题目的例子,我们对数列 {3,2,4,1} 排序后得到 {1,2,3,4} 将排列后的序列写成下面两行,第一行是数值,第二行是它们的差

1   1   0   1
-2  1  -4

将差值累加,得到 sum = -5,则重排后的结果是:

3 1 2 4

考虑将这个规律变成代码,先计算输入序列的差值,然后将差值排序,计算得到重排后的数列,最后计算得到最小值。

代码
def solve(n, a):
    # 计算差值
    diff = []
    for i in range(n-1):
        diff.append(a[i+1]-a[i])
    # 排序差值
    diff.sort()
    # 重排后的结果
    b = [0]*n
    # 前半段加偶数位,后半段加奇数位
    for i in range(n):
        if i % 2 == 0:
            b[i] = a.pop(0)
        else:
            b[i] = a.pop(-1)
    # 计算得到最小值
    res = 0
    for i in range(n-1):
        res += abs(b[i]-b[i+1])
    return res


# 测试
n = 4
a = [3,2,4,1]
print(solve(n, a)) # 5

返回结果:

5