You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MaximizeSum程序性能优化求助:大序列快速计算最大和

问题分析与优化方案

原程序用于计算移除非首尾元素最大化总点数,但存在指数级时间复杂度、IEnumerable频繁遍历开销、不必要异步操作三大问题,导致无法处理100个元素的序列。以下是针对性优化方案:

核心问题拆解

  1. 暴力递归的指数级复杂度:原代码枚举所有移除顺序,时间复杂度为O((n-2)!),n=100时完全无法计算。
  2. IEnumerable操作低效:Count()、ElementAt()、RemoveAt()均为O(n)时间操作,每次递归多次遍历序列,进一步恶化性能。
  3. 异步滥用:所有操作均为CPU密集型,异步调度反而增加额外开销。

优化思路:动态规划(戳气球变种)

该问题可转化为类似"戳气球"的动态规划问题,通过状态缓存将时间复杂度降至O(n³),空间复杂度O(n²),轻松处理n=100的场景。

状态定义

dp[i][j]:移除原序列中索引i到j之间的所有元素(不包含i和j)的最大总sum之和。

状态转移

  • 当j <= i+1时,dp[i][j] = 0(无元素可移除)。
  • 当j > i+1时,选择最后一个被移除的元素k(i < k < j),此时移除k的sum为arr[i] + arr[k] + arr[j](k的邻居为i和j),总sum为:
    dp[i][j] = max(dp[i][k] + dp[k][j] + arr[i] + arr[k] + arr[j])
    

最终结果计算

遍历所有可能的最后剩余中间元素k,总点数为:

总点数 = dp[0][k] + dp[k][n-1] + arr[0] + arr[k] + arr[n-1]

取所有k对应的最大值即为答案。

优化后代码实现

public interface ISolver<T>
{
    Task<T> SolveAsync(IEnumerable<T> sequence);
}

public class Solver : ISolver<short>
{
    public async Task<short> SolveAsync(IEnumerable<short> sequence)
    {
        var arr = sequence.ToArray();
        int n = arr.Length;
        
        if (n == 3)
            return (short)(arr[0] + arr[1] + arr[2]);
        if (n < 3)
            throw new ArgumentException("序列长度至少为3");

        short[,] dp = new short[n, n];

        // 按子序列长度从小到大计算
        for (int len = 2; len < n; len++)
        {
            for (int i = 0; i + len < n; i++)
            {
                int j = i + len;
                dp[i, j] = 0;
                for (int k = i + 1; k < j; k++)
                {
                    short current = (short)(dp[i, k] + dp[k, j] + arr[i] + arr[k] + arr[j]);
                    if (current > dp[i, j])
                    {
                        dp[i, j] = current;
                    }
                }
            }
        }

        short maxTotal = 0;
        for (int k = 1; k < n - 1; k++)
        {
            short total = (short)(dp[0, k] + dp[k, n - 1] + arr[0] + arr[k] + arr[n - 1]);
            if (total > maxTotal)
            {
                maxTotal = total;
            }
        }

        return await Task.FromResult(maxTotal);
    }
}

代码说明

  1. 数组转换:将IEnumerable转为数组,实现O(1)时间元素访问,避免频繁遍历。
  2. 动态规划填充:按子序列长度从小到大计算,确保子状态先于父状态完成计算。
  3. 异步兼容:用Task.FromResult包装结果,保持与原接口一致,无额外异步开销。
  4. 性能提升:n=100时仅需毫秒级计算,相比原代码性能提升数个数量级。

内容的提问来源于stack exchange,提问作者Gqrsw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 15:05:32