第231题 小U的加法魔法 | 豆包MarsCode AI刷题

121 阅读3分钟

题目设定

image.png

题目分析与解决方案详解

背景知识

在计算机科学中,优化问题是一个常见的研究方向。优化问题通常要求在一组备选方案中找到最优解,这需要结合数学计算、算法设计以及复杂度分析进行综合判断。本题属于“局部优化”问题,即通过一次操作改变数组中两个元素之间的运算方式(加法改为乘法),以实现整体总和的最大化。

加法和乘法在数学中具有不同的性质:

  • 加法:是线性增长操作,( a+ba + b ) 的增长速度仅与 ( a,ba, b ) 的大小成正比。
  • 乘法:是非线性增长操作,( a×ba \times b ) 的增长速度与两个数的大小呈指数级关系。 在本题中,将加法替换为乘法可能会显著增加总和,尤其是对于较大的 ( a[i]a[i] ) 和 ( a[i+1]a[i+1] ) 。

题目拆解

题目要求计算一个数组的总和 (sum)( \text{sum} ),并允许进行一次操作:将任意一对相邻元素之间的加号替换为乘号,目的是使最终的总和最大。最终我们需要找到这一最优方案,返回最大的可能总和。

输入与输出

  • 输入
    • 一个整数 ( nn ),表示数组的长度。
    • 一个整数数组 ( aa ),长度为 ( nn )。
  • 输出
    • 一个整数,表示经过一次操作后可能的最大总和。

约束分析

  • ( n2n \geq 2 ):因为需要至少一对相邻元素。
  • 元素值 ( a[i]a[i] ) 可以为任意整数,包括正数、零和负数。
  • 时间复杂度应尽可能优化。由于只需要一次遍历即可计算每种替换方案,因此 ( O(n)O(n) ) 是可行的复杂度。

解题思路
  1. 原始总和计算: 首先计算数组的原始总和 ( sum\text{sum} )。这只是所有元素的简单相加操作: [ sum=a[1]+a[2]++a[n]\text{sum} = a[1] + a[2] + \dots + a[n] ]

  2. 尝试加法替换为乘法: 遍历数组的每一对相邻元素 ( a[i],a[i+1]a[i], a[i+1] ),假设将它们的加法替换为乘法,计算新的总和: [ new_sum=suma[i]a[i+1]+(a[i]×a[i+1])\text{new\_sum} = \text{sum} - a[i] - a[i+1] + (a[i] \times a[i+1]) ] 这里的核心在于:

    • 从原始总和中移除当前两个元素的加法贡献。
    • 加入它们的乘法贡献。
  3. 记录最大值: 通过遍历所有可能的替换方案,保留 ( new_sum\text{new\_sum} ) 的最大值作为最终结果。

  4. 输出结果: 最后输出遍历中的最大总和。


代码实现

实现时,可以选择任意编程语言。以下是 C++ 的代码实现:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int solution(int n, vector<int> a) {
    // 计算原始总和
    int original_sum = 0;
    for (int num : a) {
        original_sum += num;
    }

    int max_sum = original_sum;

    // 遍历每一对相邻元素
    for (int i = 0; i < n - 1; ++i) {
        // 尝试将 a[i] + a[i+1] 替换为 a[i] * a[i+1]
        int new_sum = original_sum - a[i] - a[i + 1] + (a[i] * a[i + 1]);
        // 更新最大值
        max_sum = max(max_sum, new_sum);
    }

    return max_sum;
}

int main() {
    cout << (solution(6, {1, 1, 4, 5, 1, 4}) == 27) << endl;
    cout << (solution(3, {2, 3, 5}) == 17) << endl;
    return 0;
}

样例分析
样例 1

输入: [ n=6,a=[1,1,4,5,1,4]n = 6, a = [1, 1, 4, 5, 1, 4] ] 计算过程:

  1. 原始总和: [ sum=1+1+4+5+1+4=16\text{sum} = 1 + 1 + 4 + 5 + 1 + 4 = 16 ]
  2. 替换相邻元素:
    • 替换 ( 1,11, 1 ):( new_sum=1611+(1×1)=15\text{new\_sum} = 16 - 1 - 1 + (1 \times 1) = 15 )
    • 替换 ( 1,41, 4 ):( new_sum=1614+(1×4)=15\text{new\_sum} = 16 - 1 - 4 + (1 \times 4) = 15 )
    • 替换 ( 4,54, 5 ):( new_sum=1645+(4×5)=27\text{new\_sum} = 16 - 4 - 5 + (4 \times 5) = 27 )
    • 替换 ( 5,15, 1 ):( new_sum=1651+(5×1)=15\text{new\_sum} = 16 - 5 - 1 + (5 \times 1) = 15 )
    • 替换 ( 1,41, 4 ):( new_sum=1614+(1×4)=15\text{new\_sum} = 16 - 1 - 4 + (1 \times 4) = 15 )
  3. 最大值为 ( 27 )。
样例 2

输入: [ n=3,a=[2,3,5]n = 3, a = [2, 3, 5] ] 计算过程:

  1. 原始总和: [ sum=2+3+5=10\text{sum} = 2 + 3 + 5 = 10 ]
  2. 替换相邻元素:
    • 替换 ( 2,32, 3 ):( new_sum=1023+(2×3)=11\text{new\_sum} = 10 - 2 - 3 + (2 \times 3) = 11 )
    • 替换 ( 3,53, 5 ):( new_sum=1035+(3×5)=17\text{new\_sum} = 10 - 3 - 5 + (3 \times 5) = 17 )
  3. 最大值为 ( 17 )。

时间与空间复杂度分析
  • 时间复杂度:遍历数组一次,复杂度为 ( O(n)O(n) )。
  • 空间复杂度:仅使用常数额外空间,复杂度为 ( O(1)O(1) )。

总结

本题通过一次操作优化总和,考验了对加法与乘法性质的理解以及算法设计能力。整个解题过程结构清晰,算法时间复杂度为 ( O(n)O(n) ),高效且适合处理大规模数据。