Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>The <code>O(NK)</code> <a href="http://en.wikipedia.org/wiki/Dynamic_programming" rel="nofollow">dynamic programming</a> solution</strong> is fairly easy:</p> <p>Let <code>A[i]</code> be the best sum of the elements to the left subject to the not-<code>k</code>-consecutive constraint (assuming we're removing the <code>i</code>-th element as well).</p> <p>Then we can calculate <code>A[i]</code> by looking back <code>K</code> elements:</p> <pre><code>A[i] = 0; for j = 1 to k A[i] = max(A[i], A[i-j]) A[i] += input[i] </code></pre> <p>And, at the end, just look through the last <code>k</code> elements from <code>A</code>, adding the elements to the right to each and picking the best one.</p> <p>But this is too slow.</p> <p><strong>Let's do better.</strong></p> <p>So <code>A[i]</code> finds the best from <code>A[i-1]</code>, <code>A[i-2]</code>, ..., <code>A[i-K+1]</code>, <code>A[i-K]</code>.<br> So <code>A[i+1]</code> finds the best from <code>A[i]</code>, <code>A[i-1]</code>, <code>A[i-2]</code>, ..., <code>A[i-K+1]</code>.</p> <p>There's a lot of redundancy there - we already know the best from indices <code>i-1</code> through <code>i-K</code> because of <code>A[i]</code>'s calculation, but then we find the best of all of those except <code>i-K</code> (with <code>i</code>) again in <code>A[i+1]</code>.</p> <p>So we can just store all of them in an ordered data structure and then remove <code>A[i-K]</code> and insert <code>A[i]</code>. My choice - A <a href="http://en.wikipedia.org/wiki/Binary_search_tree" rel="nofollow">binary search tree</a> to find the minimum, along with a <a href="http://en.wikipedia.org/wiki/Circular_buffer" rel="nofollow">circular array</a> of size <code>K+1</code> of tree nodes, so we can easily find the one we need to remove.</p> <p>I swapped the problem around to make it slightly simpler - instead of finding the maximum of remaining elements, I find the minimum of removed elements and then return <code>total sum - removed sum</code>.</p> <p><strong>High-level pseudo-code:</strong></p> <pre><code>for each i in input add (i + the smallest value in the BST) to the BST add the above node to the circular array if it wrapper around, remove the overridden element from the BST // now the remaining nodes in the BST are the last k elements return (the total sum - the smallest value in the BST) </code></pre> <p><strong>Running time:</strong></p> <p><code>O(n log k)</code></p> <p><strong>Java code:</strong></p> <pre><code>int getBestSum(int[] input, int K) { Node[] array = new Node[K+1]; TreeSet&lt;Node&gt; nodes = new TreeSet&lt;Node&gt;(); Node n = new Node(0); nodes.add(n); array[0] = n; int arrPos = 0; int sum = 0; for (int i: input) { sum += i; Node oldNode = nodes.first(); Node newNode = new Node(oldNode.value + i); arrPos = (arrPos + 1) % array.length; if (array[arrPos] != null) nodes.remove(array[arrPos]); array[arrPos] = newNode; nodes.add(newNode); } return sum - nodes.first().value; } </code></pre> <p><code>getBestSum(new int[]{1,2,3,1,6,10}, 2)</code> prints <code>21</code>, as required.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload