{1,2,3,4,1,2,3,4,1}
我必须将索引乘以该内部的值。我只能从数组的左侧或右侧获取一个值。
例如:
如果我仅从左边取数字,我会得到1x1 + 2x2 + 3x3 + 4x4+ 1x5 + 2x6 + 3*7 + 4x8 + 1x9 = 109 points.
如果每次我从右端获取数字,我都会有1x1+4x2+3x3+2x4+1x5+4x6+3x7+2x8+1x9 = 101 points
如果我从左右两端交替进餐(从左边开始),我会得分1x1+1x2+2x3+4x4+3x5+3x6+4x7+2x8+1x9 = 111 points
但是,正确的解决方案是
1x1+1x2+2x3+3x4+4x5+1x6+2x7+3x8+4x9 = 121 points
我的代码非常丑陋,但是有人可以帮助我吗?
public class CandyRoll {
static int total = 0;
static int test (List<Integer> list, int index, int multiplier) {
//Base Case
if (list.size() < 1) { return -1;}
if ((list.get(index) * multiplier) == (list.get(list.size() - 1) * multiplier)){
total = total + list.get(index) * multiplier;
multiplier++;
//list.remove(index);
index++;
test(list, index, multiplier);
} else if ((list.get(index) * multiplier) < (list.get(list.size() - 1) * multiplier)) {
total = total + list.get(index) * multiplier;
multiplier++;
//list.remove(index);
index++;
test(list, index, multiplier);
} else if ((list.get(index) * multiplier) > (list.get(list.size() - 1) * multiplier)) {
total = total + list.get(list.size() - 1) * multiplier;
multiplier++;
//list.remove(list.size() - 1);
index++;
test(list, index, multiplier);
}
//Given example should be 121.
return total;
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(1);
int index = 0;
System.out.println(test(list, index, 1));
}
}
答案 0 :(得分:2)
如果您稍作调整,此问题将变得更加容易。与其将其视为索引乘以当前值,不如将其取为剩余的总和然后删除一个值。因此,拿{1,2,3,4,1,2,3,4,1}
并只从左边开始取数字,您会得到
(1+2+3+4+1+2+3+4+1) +
( 2+3+4+1+2+3+4+1) +
( 3+4+1+2+3+4+1) +
( 4+1+2+3+4+1) +
( 1+2+3+4+1) +
( 2+3+4+1) +
( 3+4+1) +
( 4+1) +
( 1)
交替会给你:
(1+2+3+4+1+2+3+4+1) +
( 2+3+4+1+2+3+4+1) +
( 2+3+4+1+2+3+4 ) +
( 3+4+1+2+3+4 ) +
( 4+1+2+3 ) +
( 4+1+2 ) +
( 1+2 ) +
( 1 )
您的最佳解决方案变为:
1x1+1x2+2x3+3x4+4x5+1x6+2x7+3x8+4x9
(1+2+3+4+1+2+3+4+1) +
( 2+3+4+1+2+3+4+1) +
( 2+3+4+1+2+3+4 ) +
( 3+4+1+2+3+4 ) +
( 4+1+2+3+4 ) +
( 1+2+3+4 ) +
( 2+3+4 ) +
( 3+4 ) +
( 4 )
以此类推。
很容易验证是否给出相同的答案。但是,通过此切换,我们现在递归地解决了原始问题的子数组问题。这使得从概念上讲出动态编程解决方案变得更加直接。一旦有了概念性的解决方案,便可以遵循代码。
答案 1 :(得分:1)
这是JavaScript的递归:
function f(A, l=0, r=A.length-1, memo={}){
if (memo.hasOwnProperty([l, r]))
return memo[[l, r]];
const i = A.length - (r - l);
if (l == r)
return memo[[l, r]] = i * A[l];
return memo[[l, r]] = Math.max(
i * A[l] + f(A, l + 1, r, memo),
i * A[r] + f(A, l, r - 1, memo)
);
}
let A = [1,2,3,4,1,2,3,4,1];
console.log(f(A));