【问题标题】:Need help in understanding the logic for the algorithm [closed]需要帮助理解算法的逻辑[关闭]
【发布时间】:2013-10-25 06:18:06
【问题描述】:

昨天Codechef有一个在线编码活动,我不知道如何解决one of the questions from it。简而言之:

给定 N 个数字列表 { a1, a2 , ..., aN },求范围 [L, R] (1 ≤ L  ≤ R ≤ N) 使总和最大化 (a1 + ... +  aL−1) - (aL + … + a em>R) + (aR+1 + … + aN)。

换句话说,您可以将列表的一个子部分乘以 -1,并希望最大化结果列表的总和。

我看了几个像this 这样的解决方案,但不知道这个人在做什么。

我该怎么办?

示例

-2 3 -1 -4 -2

现在你可以将小节 3 到 5 乘以 -1 得到

-2 3 1 4 2

这样sum(-2,3,1,4,2) = 8 是这种情况下可能的最大值

【问题讨论】:

  • 链接过期时这个问题会很垃圾
  • 链接正常
  • @InsaneCoder 如果站点管理员删除了页面怎么办?
  • 另外,你可以提供一个简短的问题描述,我不太关心剧情,角色发展很荒谬
  • 查看简短的描述

标签: java algorithm


【解决方案1】:

如果我们可以从数组中找到最小序列,那么如果我们乘以 1 将得到最大和。

例如在这个例子中:-2 3 -1 -4 -2 最小序列是-1、-4、-2。如果我们将此序列乘以 1,它将使总和最大化。所以问题是如何找到最小和序列。

O(N) 解决方案来了:

如果数组包含所有 +ve 比没有子数组需要乘以 -1。检查以下问题。 minimum sum subarray in O(N) by Kadane's algorithm

【讨论】:

    【解决方案2】:

    您展示的算法基本上计算了任何元素的最大总和和当前总和。

    注意:它构建的数组与原始元素的符号相反

    如果当前总和为负数,则拒绝原始总和并使用新元素开始新总和。

    如果当前总和是正数,那么这意味着包括以前的条目是有益的,它将当前元素添加到总和中。

    【讨论】:

    • 你能推荐一个更好的算法来完成这个任务
    • @InsaneCoder 该算法已经是 O(N) 时间复杂度。任何其他算法都应至少具有这个时间复杂度。
    • 我的意思是不同的策略
    • @InsaneCoder 接受的解决方案实际上是贪婪的,我认为没有更好的解决方案。
    【解决方案3】:

    如果我正确理解您的问题,听起来您想先找到最小子数组,然后将其乘以 -1 并添加剩余的非否定值。

    最小子数组本质上与maximum subarray problem相反:

    public class MaxSumTest {
        public static class MaxSumList{
            int s=0, e=0;
            List<Integer> maxList;
    
            public MaxSumList(List<Integer> l){
                //Calculate s and e indexes
                minSubarray(l);
    
                //Negate the minSubarray
                for(int i=s; i < e; i++)
                    l.set(i, -l.get(i));
    
                //Store list
                maxList = l;
            }
    
            public int minSubarray(List<Integer> l){
                int tmpStart = s;
                int currMin = l.get(0);
                int globalMin = l.get(0);
    
                for(int i=1; i<l.size(); i++){
                    if(currMin + l.get(i) > 0){
                        currMin = l.get(i);
                        tmpStart = i;
                    }
                    else{
                        currMin += l.get(i);
                    }
                    if(currMin < globalMin){
                        globalMin = currMin;
                        s = tmpStart;
                        e = i+1;
                    }
                }
                return globalMin;
            }
        }
        public static void main(String... args){
            MaxSumList ms = new MaxSumList(Arrays.asList(new Integer[]{-2, 3, -1, -4, -2}));
            //Prints [-2, 3, 1, 4, 2]
            System.out.println(ms.maxList);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多