给定一个带有+ ve和-ve整数的数组,找到最大总和,这样就不允许跳过2个连续的元素(即你必须至少选择其中一个元素才能继续前进)。
例如: -
10,20,30,-10,-50,40,-50,-1,-3
输出:10 + 20 + 30-10 + 40-1 = 89
答案 0 :(得分:8)
使用动态编程方法可以解决这个问题。
让 arr 为给定数组, opt 为存储最佳解决方案的数组。 opt [i] 是从元素i开始可以获得的最大总和。
opt[i] = arr[i] + (some other elements after i)
现在要解决这个问题,我们向后迭代数组 arr ,每次都存储答案 opt [i] 。 由于我们不能跳过2个连续元素,因此必须包含元素i + 1 或元素i + 2 在 opt [i] 。
因此对于每个我,opt[i] = arr[i] + max(opt[i+1], opt[i+2])
请参阅此代码以了解:
int arr[n]; // array of given numbers. array size = n.
nput(arr, n); // input the array elements (given numbers)
int opt[n+2]; // optimal solutions.
memset(opt, 0, sizeof(opt)); // Initially set all optimal solutions to 0.
for(int i = n-1; i >= 0; i--) {
opt[i] = arr[i] + max(opt[i+1], opt[i+2]);
}
ans = max(opt[0], opt[1]) // final answer.
观察 opt 数组包含 n + 2 元素。这是为了避免在我们尝试访问 opt [i + 1] 和 opt [i + 2] 时获取非法内存访问异常(内存超出范围)元素(n-1)。
答案 1 :(得分:6)
使用可以解决该问题的重复:
dp[i] = max(dp[i - 1] + a[i], <- take two consecutives
dp[i - 2] + a[i], <- skip a[i - 1])
作为练习留下的基础案例。
答案 2 :(得分:2)
如果您看到+ ve整数,请将其添加到总和中。如果你看到一个负整数,那么检查下一个最大的整数选择并将其加到总和中。
10,20,30,-10,-50,40,-50,-1,-3
为此添加10,20,30,max(-10,-50),40 max(-50,-1),因为-3旁边没有元素丢弃它。
如果是+ ve,那么最后一个元素将会求和。
答案 3 :(得分:0)
答案:
我认为这个算法会有所帮助。
1.创建一个方法,给出输出特定用户输入数组的最大总和,如T [n],其中n表示总数。元素。
2.现在这个方法将继续添加数组元素,直到它们为正。因为我们想要最大化总和,并且没有必要放弃正面元素。
3.一旦我们的方法遇到负面元素,它就会将所有连续的负面元素转移到另一个创建新数组的方法,如N [i],这样该数组将包含我们在T [n]中遇到的所有连续负面元素。 ]并返回N [i]的最大输出。
通过这种方式,我们的主要方法不受影响,并且它继续添加正元素,并且每当遇到负元素时,它不是添加它们的实数值而是添加连续负元素数组的净最大输出。
例如:T [n] = 29,34,55,-6,-5,-4,6,43,-8,-9,-4,-3,2,78 //这里n = 14
主要方法工作:
29 + 34 + 55 +(从数组[-6,-5,-4]的辅助方法发送数据和获取值)+ 6 + 43 +(从数组的辅助方法发送数据&amp;获取值[-8, -9,-4,-3])+ 2 + 78
进程以最大输出终止。
二级方法工作:
{
N [i] =在需要时从Main方法或其自身获取数组。
这基本上是一种递归方法。
说N [i]有像N1,N2,N3,N4等元素。
对于i&gt; = 3:
现在选择就是这样。
1.如果我们取N1那么我们可以递归左关闭阵列,即N [i-1],它具有相同顺序的除N1之外的所有元素。这样净最大输出就是
N1 +(递归发送数据并从数组N [i-1]的辅助方法获取值)
2.如果我们不采用N1,那么我们就不能跳过N2。所以,现在算法就像第一选择,但从N2开始。所以在这种情况下最大输出将是
N2 +(递送数据并从数组N [i-2]的辅助方法中获取值)。
这里N [i-2]是包含除N1和N之外的所有N [i]个元素的数组。 N2以相同的顺序。
终止:当我们留下大小为1的数组(对于N [i-2])时,我们必须选择该特定值作为无选项。
递归最终将产生最大输出,我们必须最终选择更多的选择输出。
并将最大输出重定向到需要的位置。
对于i = 2:
我们必须选择更大的价值
对于i = 1:
我们当然可以跳过这个价值。
因此,在这种情况下,最大输出将为0。
}
答案 4 :(得分:0)
我认为这个答案会对你有帮助。
给定数组:
Given:- 10 20 30 -10 -50 40 -50 -1 -3
Array1:-10 30 60 50 10 90 40 89 86
Array2:-10 20 50 40 0 80 30 79 76
取最大值array1[n-1],array1[n],array2[n-1],array2[n] i.e 89(array1[n-1])
算法: -
rray1[0]=a[0],array1=a[0]+a[1]
和array2[0]=a[0],array2[1]=a[1]
。计算从2到n的array1值是array1[i-1]+a[i]
或array1[i-2]+a[i]
之和的最大值。
for loop from 2 to n{
array1[i]=max(array1[i-1]+a[i],array1[i-2]+a[i]);
}
类似于array2从2到n的值是array2[i-1]+a[i]
或array2[i-2]+a[i].
for loop from 2 to n{
array2[i]=max(array2[i-1]+a[i],array2[i-2]+a[i]);
}
最后找到array1[n-1],array[n],array2[n-1],array2[n]
;
int max(int a,int b){
return a>b?a:b;
}
int main(){
int a[]={10,20,30,-10,-50,40,-50,-1,-3};
int i,n,max_sum;
n=sizeof(a)/sizeof(a[0]);
int array1[n],array2[n];
array1[0]=a[0];
array1[1]=a[0]+a[1];
array2[0]=a[0];
array2[1]=a[1];
for loop from 2 to n{
array1[i]=max(array1[i-1]+a[i],array1[i-2]+a[i]);
array2[i]=max(array2[i-1]+a[i],array2[i-2]+a[i]);
}
--i;
max_sum=max(array1[i],array1[i-1]);
max_sum=max(max_sum,array2[i-1]);
max_sum=max(max_sum,array2[i]);
printf("The max_sum is %d",max_sum);
return 0;
}
Ans:max_sum是89
答案 5 :(得分:0)
public static void countSum(int[] a) {
int count = 0;
int skip = 0;
int newCount = 0;
if(a.length==1)
{
count = a[0];
}
else
{
for(int i:a)
{
newCount = count + i;
if(newCount>=skip)
{
count = newCount;
skip = newCount;
}
else
{
count = skip;
skip = newCount;
}
}
}
System.out.println(count);
}
}
答案 6 :(得分:0)
让数组的大小为N,索引为1 ... N
设f(n)为函数,它为子数组(1 ... n)的最大和提供答案,这样就不会有两个剩余的元素是连续的。
f(n) = max (a[n-1] + f(n-2), a(n) + f(n-1))
在第一个选项中,即 - {a [n-1] + f(n-2)},我们将离开最后一个元素,并且由于所讨论的条件选择第二个最后一个元素。
在第二个选项中, - {a(n)+ f(n-1)}我们选择子数组的最后一个元素,因此我们可以选择/取消选择第二个最后一个元素。
现在从基础案例开始:
f(0) = 0 [Subarray (1..0) doesn't exist]
f(1) = (a[1] > 0 ? a[1] : 0); [Subarray (1..1)]
f(2) = max( a(2) + 0, a[1] + f(1)) [Choosing atleast one of them]
继续前进,我们可以计算任何f(n),其中n = 1 ... N,并存储它们以计算下一个结果。是的,显然,案例f(N)将给我们答案。
Time complexity o(n)
Space complexity o(n)
答案 7 :(得分:0)
public static int sumz(int a[])
{
int total=0;
boolean isSkipped=false;
for(int i=0;i<a.length;i++)
{
if(a[i]<0) // we check when value is less than 0
{
if(i+1<a.length) //to check next element we compare whether next element consist in array or not
{
if(a[i]>=a[i+1]||isSkipped) // here we check next element less than current element
{
if(a[i]==a[i+1]) //if its equal to current than we check next to next element to decide this skip
{
if(i+2<a.length)
{
if(a[i+2]>a[i+1]) // here we check next to next element if its greater than next than we skip current element
{
isSkipped=true;
}else{
isSkipped=false; // or else we take current element
total=total+a[i];
}
}
else{
total=total+a[i];
isSkipped=false;
}
}
else{
isSkipped=false; // here if its bigger than next we take it and make isSkipped false as we didnt skipped the element
total=total+a[i];
}
}
else if(isSkipped) //if previous element is skipped than we have to take this elements
{
total=total+a[i];
isSkipped=false;
}
else // if it failes all condition than we skip element
{
isSkipped=true;
}
}
else if(isSkipped==false && a[i]>0) //if its last element and last element is not skipped and its greater than 0 than we add it in total
{
total=total+a[i];
isSkipped=false;
}
}
else
{
isSkipped=false; // value which are greater than 0 are added directly
total=a[i]+total;
}
}
return total;
}
答案 8 :(得分:0)
n = arr.length()。 在数组末尾附加0以处理边界情况。 ans:大小为n + 1的int数组。 ans [i]将存储数组a [0 ... i]的答案,其中包括答案和中的[i]。 现在,
ans[0] = a[0]
ans[1] = max(a[1], a[1] + ans[0])
for i in [2,n-1]:
ans[i] = max(ans[i-1] , ans[i-2]) + a[i]
最终答案是[n]
答案 9 :(得分:0)
如果您想避免使用动态编程
我们只会跳过负面元素。既然我们不是 允许跳过2个连续元素,我们将把所有连续 临时数组中的负元素,可以计算出最大总和 使用如下定义的sum_odd_even函数的替代元素。
然后我们可以将所有这些临时数组的最大值添加到我们的总和中 正数。最后的总和将为我们提供所需的输出。
代码:
def sum_odd_even(arr):
sum1 = sum2 = 0
for i in range(len(arr)):
if i%2 == 0:
sum1 += arr[i]
else:
sum2 += arr[i]
return max(sum1,sum2)
input = [10, 20, 30, -10, -50, 40, -50, -1, -3]
result = 0
temp = []
for i in range(len(input)):
if input[i] > 0:
result += input[i]
if input[i] < 0 and i != len(input)-1:
temp.append(input[i])
elif input[i] < 0:
temp.append(input[i])
result += sum_odd_even(temp)
temp = []
else:
result += sum_odd_even(temp)
temp = []
print result
答案 10 :(得分:0)
简单的解决方案:略过扭曲:)。如果连续-ve,只需跳过i&i + 1中最小的数字。有条件的话要检查直到n-2个元素,最后检查最后一个元素。
int getMaxSum(int[] a) {
int sum = 0;
for (int i = 0; i <= a.length-2; i++) {
if (a[i]>0){
sum +=a[i];
continue;
} else if (a[i+1] > 0){
i++;
continue;
} else {
sum += Math.max(a[i],a[i+1]);
i++;
}
}
if (a[a.length-1] > 0){
sum+=a[a.length-1];
}
return sum;
}
答案 11 :(得分:0)
正确的复发如下:
dp[i] = max(dp[i - 1] + a[i], dp[i - 2] + a[i - 1])
第一种情况是我们选择第i个元素的情况。第二种情况是我们跳过第i个元素的情况。在第二种情况下,我们必须选择第(i-1)个元素。
IVlad答案的问题在于,它总是选择第i个元素,这可能导致答案不正确。