dynamic programming - calcular la suma máxima si se selecciona el mismo número del segmento continuo
dynamic-programming (2)
La respuesta de @ גלעד ברקן es correcta y debe ser aceptada. Sin embargo, decidí implementar la solución de pila por interés y ayudar a @xyz a resolverlo.
let a = [5,5,4,4,6];
console.log(`Answer: ${traverse(a)}`);
function traverse(a) {
let i, max = 0, stack = [0];
for (i = 1; i < a.length; i++) {
if (a[i] >= a[stack[stack.length - 1]]) {
stack.push(i);
} else {
pop(i);
stack.push(i);
}
}
if (stack.length) pop(i, true);
function pop(index, end) {
while (stack.length && (a[stack[stack.length - 1]] >= a[index] || end)) {
let p = stack.pop();
let range = stack.length ? index - stack[stack.length - 1] - 1 : index;
max = Math.max(max, range * a[p]);
}
}
return max;
}
calcular la suma máxima si se selecciona el mismo número del segmento continuo
[1,2,3,4] => answer 6
if 1 is picked from continuous segment [1,1,1,1] then sum is 4
if 2 is picked from continuous segment [2,3,4] then sum is 6 ,
[6,0,6,5,5,2] => answer 15, continuous segment [6,5,5] ,
5 can be picked from 3 elements.
[1,100,1,1] => answer 100, we can''t pick 1 as 1+1+1+1 = 4 <100
No puedo pensar en ninguna solución excepto el bucle O (n ^ 2)
O(n)
complejidad. Usa una pila. Mientras que los números están aumentando los índices de empuje para apilar. Si el número es igual o inferior o la matriz finaliza, extraiga los índices de números iguales o mayores de la pila y calcule. Continuar.
Código de JavaScript:
function f(arr){
let stack = [0];
let best = arr[0];
function collapse(i, val){
console.log(`Collapsing... i: ${i}; value: ${val}`);
while (stack.length && arr[ stack[stack.length - 1] ] >= val){
let current_index = stack.pop();
let left_index = stack.length ? stack[stack.length - 1] : -1;
console.log(`i: ${i}; popped: ${current_index}; value: ${arr[current_index]}; potential: ${i - left_index - 1} * ${arr[current_index]}`)
best = Math.max(best, (i - left_index - 1) * arr[current_index]);
}
}
console.log(''Starting... stack: '' + JSON.stringify(stack));
for (let i=1; i<arr.length; i++){
if (!stack.length || arr[ stack[stack.length - 1] ] < arr[i]){
stack.push(i);
console.log(`Pushing ${i}; stack: ${JSON.stringify(stack)}`);
} else {
collapse(i, arr[i]);
stack.push(i);
console.log(`Pushing ${i}; stack: ${JSON.stringify(stack)}`);
}
}
if (stack.length)
collapse(stack[stack.length - 1] + 1, -Infinity);
return best;
}
//console.log(f([5,5,4]))
//console.log(f([1,2,3,4]))
console.log(f([6,0,6,5,5,2]))