Write an algorithm that, given sequence seq of n numbers where 3 <= n <= 1000 and each number k in seq 1 <= k <= 200, finds maximum sum by repeatedly removing one number from seq, except for first and last number in seq, and adding its value to sum of two adjacent numbers. Algorithm ends when there are only two numbers left.

For example: Max sum for sequence [2, 1, 5, 3, 4] is 31.

So far I've written brute force algorithm checking all possible combinations but it's not well suited for large sequences.

public static int solve(ArrayList<Integer> seq, int sumOfRemoved) {
  if (seq.size() == 3) {
    return seq.get(0) + seq.get(1) + seq.get(2) + sumOfRemoved;
  LinkedList<Integer> maxValues = new LinkedList<>();
  for (int i = 1; i < seq.size() - 1; i++) {
    ArrayList<Integer> clone = (ArrayList<Integer>) seq.clone();
    int sum = seq.get(i - 1) + seq.get(i) + seq.get(i + 1);
    maxValues.add(solve(clone, sum));
  int max = 0;
  for (int val : maxValues) {
    max = Math.max(max, val + sumOfRemoved);
  return max;

My question is, is there more efficient algorithm solving this problem?


From the top of my head I would use a greedy approach, always remove the lowest available number so the potential sum of later steps lessens the least this way. But I do not have a proof for this finding the top possible sum, especially not at 0:21 on Monday :-).

With 2,1,5,3,4(0) it would go to 2,5,3,4(2+1+5=8), then to 2,5,4(8+5+3+4=20), and end at 2,4(20+2+5+4=31). So it finds your sum, but this is just one case.


Not the answer you're looking for? Browse other questions tagged or ask your own question.