我得到了一个整数数组。我需要找到其元素的最大总和,以便任何两个元素不是邻居。示例:sum(2,5,2)= 5因为我们只选择5;总和(3,10,2,4,10)= 20,因为我们选择10和10; sum(10,12,5,2)= 15因为我们选择10和5。 如何使用任何编程语言完成? 我一直在研究这个问题几个小时,我唯一理解它应该使用DP。
答案 0 :(得分:1)
所以我在没有使用DP的情况下用Java实现了一个解决方案;我只是使用了递归。我会试着解释一下。
首先,我们必须找到一个基本案例:
现在,让我们来看看array.length = n的一般情况。我们必须决定数组[n-1]是否是解决方案的一部分;也就是说,如果在第一个n-1个元素上启动的sum小于在数组的第一个n-2个元素+第n个元素上启动的sum。
简而言之,我们说“考虑第n个元素或其邻居(nth-1)是否更好?”实际上,我们不能同时考虑两者,因此我们必须选择一个。
private static int sum (int[] array) {
return aux (array,array.length);
}
private static int aux (int[] array, int upTo) {
if (upTo == 1)
return array[0];
else if (upTo == 2)
return (array[1] > array[0])
? array[1] : array[0];
else {
int tmpMax1 = aux (array,upTo-1);
int tmpMax2 = aux (array,upTo-2) + array[upTo-1];
return (tmpMax2 > tmpMax1)
? tmpMax2 : tmpMax1;
}
}
public static void main(String[] args) {
//just a bunch of simple tests. Too lazy to use JUnit
System.out.println(sum(new int[]{2}) + " = 2");
System.out.println(sum(new int[]{2, 5}) + " = 5");
System.out.println(sum(new int[]{2, 5, 2}) + " = 5");
System.out.println(sum(new int[]{3, 10, 2, 4, 10}) + " = 20");
System.out.println(sum(new int[]{10, 12, 5, 2}) + " = 15");
System.out.println(sum(new int[]{10, 12, 5, 2,100}) + " = 115");
System.out.println(sum(new int[]{10, 10, 10, 10,100}) + " = 120");
}