在最多可以省略k个元素的情况下找到最大和连续子数组?

时间:2019-03-30 04:22:04

标签: algorithm c++11 dynamic-programming

例如-html: <div class="photo"> <img src="..."> </div> css: .photo { width: 300px; height: 400px; border: 1px solid black; overflow: visible; margin-top: 20px; margin-left: 20px; } img { height: 100%; width: auto; float: right; }
n=10
arr[]={6,-5,3,-7,6,-1,10,-8,-8, 8}
给定数组和k,求和。

我认为,让For k=0, best segment is 5-7 with sum=15. For k=2, best segment is 1-7 with sum=24. For k=6, best segment is 1-10 with sum=33.表示在位置i处结束的最大段,最多丢弃j个元素。从dp[i][j]归纳计算dp[i][j]。但是如何跟踪从dp[i][j-1]中删除的元素,而不是再次删除它们呢???我对dp问题感到困惑。我想知道dp方法和其他方法(如果可能)?

1 个答案:

答案 0 :(得分:1)

m(i, j)代表以索引i结尾的最大和,恰好有k省略。然后

m(i, j) = max(
  // Use A[i-1]
  // (same number of omissions: j)
  A[i-1] + max(0, m(i - 1, j)),

  // Omit A[i-1]
  // (reference j-1 since we are
  // adding an omission here)
  m(i - 1, j - 1)
)

要获得最多 k个遗漏的答案,我们考虑所有不同的确切k的结果。 (请注意,由于只需要前一行和当前行,因此该空间仍可以减少到O(n)。)

JavaScript代码:

function f(A, k){
  console.log(`Input: ${ JSON.stringify(A) }\n\n`);

  let m = new Array(A.length + 1);
  
  let result = 0;

  // Initialize Array
  for (let i=0; i<=A.length; i++)
    m[i] = new Array(k + 1).fill(0);

  // Zero omissions (Kadane's algorithm)
  for (let i=1; i<=A.length; i++){
    m[i][0] = A[i-1] + Math.max(0, m[i-1][0]);
    result = Math.max(result, m[i][0]);
  }
  
  for (let i=1; i<=A.length; i++){
    for (let j=1; j<=k; j++){
      m[i][j] = Math.max(
        A[i-1] + Math.max(0, m[i-1][j]),
        m[i-1][j-1]
      );
      
      result = Math.max(result, m[i][j]);
    }
  }
  
  for (let row of m)
    console.log(JSON.stringify(row));
    
  return result;
}

let A = [6, -5, 3, -7, 6, -1, 10, -8, -8, 8];
let k = 6;

console.log(f(A, k));