📅  最后修改于: 2023-12-03 15:23:03.950000             🧑  作者: Mango
给定一个长度为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