问题描述
小C希望构造一个包含n个元素的数组,且满足以下条件:
- 数组中的所有元素两两不同。
- 数组所有元素的最大公约数为
k。 - 数组元素之和尽可能小。
任务是输出该数组元素之和的最小值。
测试样例
样例1:
输入:
n = 3 ,k = 1
输出:6
样例2:
输入:
n = 2 ,k = 2
输出:6
样例3:
输入:
n = 4 ,k = 3
输出:30问题分析
需要在一个二维网格中找到一条路径,满足以下条件:
- 路径上的每个点的高度必须不同。
- 路径上的点必须交替上坡和下坡。
- 路径的长度尽可能长。
解题思路
-
深度优先搜索(DFS) :
- 由于需要找到一条满足条件的路径,可以使用DFS来遍历所有可能的路径。
- 从每个点开始进行DFS,记录当前路径的长度,并更新最大路径长度。
-
记忆化搜索(Memoization) :
- 为了避免重复计算,可以使用一个记忆化数组
memo来存储每个点的最大路径长度。 - 如果某个点已经被计算过,直接返回其记忆化的结果,避免重复计算。
- 为了避免重复计算,可以使用一个记忆化数组
-
方向判断:
- 在DFS过程中,需要判断当前点是否可以移动到下一个点。
- 如果当前点是起点(
lastMove == 0),则可以上坡或下坡。 - 如果当前点是上坡(
lastMove == 1),则下一个点必须是下坡。 - 如果当前点是下坡(
lastMove == 2),则下一个点必须是上坡。
算法步骤
-
初始化:
- 创建一个记忆化数组
memo,用于存储每个点的最大路径长度。
- 创建一个记忆化数组
-
遍历每个点:
- 对于每个点,调用DFS函数,计算从该点开始的最大路径长度。
-
DFS函数:
- 如果当前点已经被计算过(
memo[x][y] != 0),直接返回记忆化的结果。 - 否则,遍历当前点的四个方向(上下左右),判断是否可以移动到下一个点。
- 如果可以移动,递归调用DFS函数,并更新当前点的最大路径长度。
- 将当前点的最大路径长度存储到
memo数组中。
- 如果当前点已经被计算过(
-
返回结果:
- 返回所有点中最大路径长度的最大值。
完整代码
def solution(n: int, k: int) -> int:
# 计算 1 + 2 + 3 + ... + n 的和
sum_of_first_n = n * (n + 1) // 2
# 乘以 k 得到最终的和
return k * sum_of_first_n
if __name__ == '__main__':
print(solution(n = 3, k = 1) == 6) # 1+2+3 = 6
print(solution(n = 2, k = 2) == 6) # 2+4 = 6
print(solution(n = 4, k = 3) == 30) # 3+6+9+12 = 30