Count of strictly increasing sequence of integers - arrays

You are given two list of integers a and b of same length n, Find the count of strictly increasing sequences of integers
I[0] < I[1] < .. < I[n-1] such that min(a[i], b[i]) <= I[i] <= max(a[i], b[i]) for each i.
Eg.
a = [6,3,4,4]
b = [1,5,1,6]
Four possible solutions are possible
[1 3 4 5],
[1 3 4 6],
[2 3 4 5],
[2 3 4 6].
The length of both arrays will not exceed 100.
Each element is between 1 and 10000.```
Can someone provide a hint for this question? I am not able to figure out

You can use a dynamic programming approach here. The states of your DP will be the current index and last value ,like count_sequence(int index, int last_value) , loop through min(a[index], b[index]) to max(a[index], b[index]) ,if there is a value greater then last_value go to next index with current value like count_sequence(index+1, current_value), if you reach base case which is index>=n that means you find a sequence then return 1. Using this you can find every possible sequence.
With memorization, the complexity will be O(n*m),
n = array size, m = maximum element

JavaScript/node.js solution:
const a = [6, 3, 4, 4]
const b = [1, 5, 1, 6]
const n = a.length
let min = []
let max = []
for (let i = n - 1; i >= 0; i--) {
let itemMin = (min[i] = Math.min(a[i], b[i]))
let itemMax = (max[i] = Math.max(a[i], b[i]))
if (i > 0) {
const maxBefore = Math.max(a[i - 1], b[i - 1])
// max of before index, >= current min
if (maxBefore >= min[i]) {
itemMin = Math.min(maxBefore + 1, max[i])
}
}
if (i < n - 1) {
const minAfter = min[i + 1]
// min of after index, <= current or calculated min
if (itemMin >= minAfter) {
itemMin = Math.min(minAfter - 1, min[i])
}
// max correction
itemMax = Math.min(max[i], minAfter - 1)
}
// Test is solution possible, if not do something
if (itemMin < min[i] || itemMin > max[i]) {
throw new Error('Impossible to solve...')
}
if (itemMax < min[i] || itemMax > max[i]) {
throw new Error('Impossible to solve...')
}
// Set min and max values
min[i] = itemMin
max[i] = itemMax
}
// ***** Printing results
function printResult(min, max, str = '', item = 0) {
const n = min.length
for (let j = min[item]; j <= max[item]; j++) {
if (item < n - 1) {
printResult(min, max, `${item !== 0 ? str : ''}${j},`, item + 1)
} else {
console.log(`[${str}${j}]`)
}
}
}
printResult(min, max)

Given two arrays, one holding the min value and the other the max value for each index, you could define a simple recursive function to derive each possible increasing sequence, with the starting value at each position being the maximum of the current min value and the previously selected value plus 1.
Here's some Java code to illustrate:
static void incSeq(int[] min, int[] max, int[] res, int pos, int prev)
{
if(pos == min.length)
{
System.out.println("seq: " + Arrays.toString(res));
return;
}
for(int j = Math.max(prev+1, min[pos]); j <= max[pos]; j++)
{
res[pos] = j;
incSeq(min, max, res, pos+1, j);
}
}
However, if we consider input such as:
min = {1, 1, 1, 1}
max = {100, 100, 100, 5}
we can see that our function is going to do a lot of useless work iterating through values in the first three positions that will not be part of an increasing sequence.
We can fix this by recognizing that the maximum value we need to consider for position i is one less that the max value at position i+1. If we start at the last position and work backwards using this rule we can update the max array above to:
max = {2, 3, 4, 5}
Which will mean a lot less work for our recursive function.
Here's the complete code:
public static void main(String[] args)
{
int n = 4;
int[] a = {6,3,4,4};
int[] b = {1,5,1,6};
int[] min = new int[n];
int[] max = new int[n];
System.out.println("a: " + Arrays.toString(a));
System.out.println("b: " + Arrays.toString(b));
for(int i=0; i<n; i++)
{
min[i] = Math.min(a[i], b[i]);
max[i] = Math.max(a[i], b[i]);
}
System.out.println("min: " + Arrays.toString(min));
System.out.println("max: " + Arrays.toString(max));
// cap max values
for(int i=n-1; i>0; i--)
{
max[i-1] = Math.min(max[i-1], max[i]-1);
}
System.out.println("max: " + Arrays.toString(max) + "\n");
incSeq(min, max, new int[n], 0, 0);
}
static void incSeq(int[] min, int[] max, int[] res, int pos, int prev)
{
if(pos == min.length)
{
System.out.println("seq: " + Arrays.toString(res));
return;
}
for(int j = Math.max(prev+1, min[pos]); j <= max[pos]; j++)
{
res[pos] = j;
incSeq(min, max, res, pos+1, j);
}
}
Output:
a: [6, 3, 4, 4]
b: [1, 5, 1, 6]
min: [1, 3, 1, 4]
max: [6, 5, 4, 6]
max: [2, 3, 4, 6]
seq: [1, 3, 4, 5]
seq: [1, 3, 4, 6]
seq: [2, 3, 4, 5]
seq: [2, 3, 4, 6]

Related

What is the minimum number of swaps needed so that the difference of sums of arrays a and b is minimum?

Given 2 arrays of integers a[] and b[] with the same size of n (1 <= n <= 100) numbered from 1 to n.
(0 <= a[i], b[i] <= 6)
You can swap any a[i] with b[i].
What is the minimum number of swaps needed so that the difference of the sums of array a[] and b[] is minimum ?
Then print out:
The number of swaps
The swapped indexes
The difference of sums of both arrays
Example
n = 6
a[] = { 1, 1, 4, 4, 0, 6 }
b[] = { 6, 3, 1, 1, 6, 1 }
Result
- 2 (The number of swaps)
- 5, 6 (The swapped indexes)
- 0 (The difference of sums of the arrays)
Explanation
If you swap a[5] with b[5] and a[6] with b[6] which requires 2 swaps, arrays a[] and b[] will become:
a[] = {1, 1, 4, 4, 6, 1}
b[] = {6, 3, 1, 1, 0, 6}
Sum of a[] is 1 + 1 + 4 + 4 + 6 + 1 = 17
Sum of b[] is 6 + 3 + 1 + 1 + 0 + 6 = 17
So the difference of the two sums is 0.
Here's an iterative method that saves the differences so far and updates the smallest list of indexes needed to swap to achieve them.
JavaScript code:
function update(obj, d, arr){
if (!obj[d] || obj[d].length > arr.length)
obj[d] = arr;
}
function f(A, B){
let diffs = {0: []};
for (let i=0; i<A.length; i++){
const newDiffs = {};
for (d in diffs){
// Swap
let d1 = Number(d) + B[i] - A[i];
if (diffs.hasOwnProperty(d1) && diffs[d1].length < diffs[d].length + 1)
update(newDiffs, d1, diffs[d1]);
else
update(newDiffs, d1, diffs[d].concat(i+1));
d1 = Number(d) + A[i] - B[i];
if (diffs.hasOwnProperty(d1) && diffs[d1].length < diffs[d].length)
update(newDiffs, d1, diffs[d1]);
else
update(newDiffs, d1, diffs[d]);
}
diffs = newDiffs;
}
console.log(JSON.stringify(diffs) + '\n\n');
let best = Infinity;
let idxs;
for (let d in diffs){
const _d = Math.abs(Number(d));
if (_d < best){
best = _d;
idxs = diffs[d];
}
}
return [best, idxs];
};
var A = [1, 1, 4, 4, 0, 6];
var B = [6, 3, 1, 1, 6, 1];
console.log(JSON.stringify(f(A, B)));
Here's a C++ implementation of mine based on Javascript answer of גלעד ברקן.
Short Explanation:
We maintain a mapping of all differences and their minimum swaps seen so far and try to extend all of the differences seen so far based on new values to get new mapping of such kind. We have 2 choices at each step when considering ith items in A and B, either consider the items as it is or swap the ith items.
Code:
#include <iostream>
#include <climits>
#include <unordered_map>
#include <vector>
using namespace std; // Pardon me for this sin
void update_keeping_existing_minimum(unordered_map<int, vector<int> >& mp, int key, vector<int>& value){
if(mp.find(key) == mp.end() || mp[key].size() > value.size())mp[key] = value;
}
// Prints minimum swaps, indexes of swaps and minimum difference of sums
// Runtime is O(2^size_of_input) = 2^1 + 2^2 .. + 2^n = 2*2^n
// This is a bruteforce implementation.
// We try all possible cases, by expanding our array 1 index at time.
// For each previous difference,
// we use new index value and expand our possible difference outcomes.
// In worst case we may get 2 unique differences never seen before for every index.
void get_minimum_swaps(vector<int>& a, vector<int>& b){
int n = a.size();
unordered_map<int, vector<int> > prv_differences_mp;
prv_differences_mp[0] = {}; // initial state
for(int i = 0 ; i < n ; i++){
unordered_map<int, vector<int> > new_differences_mp;
for (auto& it: prv_differences_mp) {
// possibility 1, we swap and expand previous difference
int d = it.first;
int d1 = d + b[i] - a[i];
if(prv_differences_mp.find(d1) != prv_differences_mp.end() && prv_differences_mp[d1].size() < (prv_differences_mp[d].size() + 1)){
update_keeping_existing_minimum(new_differences_mp, d1, prv_differences_mp[d1]);
} else {
// only place we are modifying the prv map, lets make a copy so that changes don't affect other calculations
vector<int> temp = prv_differences_mp[d];
temp.push_back(i+1);
update_keeping_existing_minimum(new_differences_mp, d1, temp);
}
// possibility 2, we don't swap and expand previous difference
int d2 = d + a[i] - b[i];
if(prv_differences_mp.find(d2) != prv_differences_mp.end() && prv_differences_mp[d2].size() < prv_differences_mp[d].size()){
update_keeping_existing_minimum(new_differences_mp, d2, prv_differences_mp[d2]);
} else {
update_keeping_existing_minimum(new_differences_mp, d2, prv_differences_mp[d]);
}
}
cout<<i<<":index\n";
for(auto& it: prv_differences_mp){
cout<<it.first<<": [ ";
for(auto& item: it.second)cout<<item<<" ";
cout<<"] ; ";
}
cout<<"\n";
prv_differences_mp = new_differences_mp;
}
int best = INT_MAX;
vector<int> min_swap_ans;
for(auto& it: prv_differences_mp){
int _d = it.first >= 0 ? it.first: -it.first;
if(_d < best){
best = _d;
min_swap_ans = it.second;
}
}
cout<<"Number of swaps: "<<min_swap_ans.size()<<"\n";
cout<<"Swapped indexes:\n";
for(auto idx: min_swap_ans)cout<<idx<<" ";
cout<<"\nDifference: "<<best<<"\n";
}
int main(){
vector<int> A{ 1, 1, 4, 4, 0, 6 };
vector<int> B{ 6, 3, 1, 1, 6, 1 };
get_minimum_swaps(A, B);
return 0;
}

Google Kick Start Time Limited on Dart

I found out that my code Time Limited, but algorithm is just fine i believe. Is it my code problem or language?
Here is the task: Task src
An arithmetic array is an array that contains at least two integers and the differences between consecutive integers are equal. For example, [9, 10], [3, 3, 3], and [9, 7, 5, 3] are arithmetic arrays, while [1, 3, 3, 7], [2, 1, 2], and [1, 2, 4] are not arithmetic arrays.
Sarasvati has an array of N non-negative integers. The i-th integer of the array is Ai. She wants to choose a contiguous arithmetic subarray from her array that has the maximum length. Please help her to determine the length of the longest contiguous arithmetic subarray.
import 'dart:io';
import 'dart:math';
foo (array){
var diff = [];
var size = 2;
var answ = 2;
for (int i = 0; i < array.length - 1; i++){
diff.add(array[i + 1] - array[i]);
}
for (int i = 1; i < diff.length; i++){
if (diff[i] == diff[i - 1]){
size++;
}
else{
size = 2;
}
answ = max(answ, size);
}
return answ;
}
void main() {
var N = int.parse(stdin.readLineSync());
for (int i = 0; i < N; i++){
var M = int.parse(stdin.readLineSync());
String s = stdin.readLineSync();
var intArray = [];
s.trim().split(" ").forEach((x) => intArray.add(int.parse(x)));
print("Case #${i + 1}: ${foo(intArray)}");
}
}

How to generate all subsequence of even length from an array?

I am dealing with a problem and that problem requires the answer to this as a subroutine. I know how to generate all subsequences from an array using bit manipulation but struggling to generate subsequences of even length.
For the sake of example, assume that there is an array A = [2, 5, 4, 2, 3, 1]
I want all the subsequences of even length i.e., of length 2, 4, and 6.
Edit 1: 1<=N<=1000 where N is the size of the array.
Since you already know how to generate all subsequences, then just remove the last element and generate all subsequences of the remaining array, but append the last back to each subsequence with an odd length.
Easy to prove that this generates all the even-length subsequences:
Every even-length subsequence of A that does not end in the last element of A, is an even-length subsequence of the earlier elements.
Every even-length subsequence of A that does end in the last element of A, has that element preceded by an odd-length subsequence of the earlier elements.
Subarrays
Using generator functions, you can take advantage of deferred execution to iterate all of the even-lengthed subarrays without retaining the entire collection of subarrays in memory:
function * subarrays (array) {
for (let length = 1; length <= array.length; length++) {
for (let index = 0; index + length <= array.length; index++) {
yield array.slice(index, index + length);
}
}
}
const filter = predicate => function * (iterator) {
for (const value of iterator) {
if (predicate(value)) yield value;
}
};
const even = filter(subarray => subarray.length % 2 === 0);
for (const subarray of even(subarrays ([2, 5, 4, 2, 3, 1]))) {
console.log(subarray.join());
}
However, if you do want the entire collection of even-lengthed subarrays, you can use Array.from() to consume the iterator and populate an array of subarrays:
function * subarrays (array) {
for (let length = 1; length <= array.length; length++) {
for (let index = 0; index + length <= array.length; index++) {
yield array.slice(index, index + length);
}
}
}
const filter = predicate => function * (iterator) {
for (const value of iterator) {
if (predicate(value)) yield value;
}
};
const even = filter(subarray => subarray.length % 2 === 0);
const result = Array.from(even(subarrays([2, 5, 4, 2, 3, 1])));
console.log(JSON.stringify(result));
Subsequences
To iterate all even-lengthed subsequences, one of the easiest methods is to keep a lookup table of which values to filter() from the array. We can achieve this with fairly minimal memory overhead by leveraging a Uint32Array:
function _increment (uint32Array) {
for (let index = 0; index < uint32Array.length; index++) {
// use unsigned integer overflow to
// perform carry in base 2**32 addition
if (++uint32Array[index]) return;
}
}
function * subsequences (array) {
const lut = new Uint32Array(Math.ceil(array.length / 32));
let subsequence;
while (true) {
yield subsequence = array.filter(
(_, index) => (lut[index >>> 5] >>> (index % 32)) & 1
);
if (subsequence.length === array.length) return;
_increment(lut);
}
}
const filter = predicate => function * (iterator) {
for (const value of iterator) {
if (predicate(value)) yield value;
}
};
const even = filter(({ length }) => (length > 0) && (length % 2 === 0));
for (const subsequence of even(subsequences([2, 5, 4, 2, 3, 1]))) {
console.log(subsequence.join());
}
#include <stdio.h>
#define N 4
const int A[] = { 2, 5, 4, 2, 3, 1, -1 };
int out[1000];
void gen(const int *p, int *pout) {
if(pout - out < N) {
while((*pout = *p++) > 0)
gen(p, pout + 1);
} else { // print output
for(const int *o = out; o < pout; o++)
printf("%d ", *o);
putchar('\n');
}
}
int main(int argc, char **argv) {
gen(A, out);
return 0;
}
Here's Python, which is as good as pseudocode:
def even_subsequences(L):
# yield the empty subsequence
yield []
# iterate over subsequence starting points
for i in range(len(L)):
# subsequence end point is the starting point plus an even number
for j in range(i+2, len(L)+1, 2):
# slice the list
yield L[i:j]
>>> list(even_subsequences([1,2,3,4,5,6]))
[[],
[1, 2],
[1, 2, 3, 4],
[1, 2, 3, 4, 5, 6],
[2, 3],
[2, 3, 4, 5],
[3, 4],
[3, 4, 5, 6],
[4, 5],
[5, 6]]

Find next smallest value in array?

This question has been eating at me for a while. Basically, if you have an input array [4, 5, 2, 6, 7, 1], the next smallest number for 4 and 5 is 2, and for 6 and 7 is 1. I need to identify these smaller numbers. I have an obvious n^2 solution in time, but I feel there is an O(n) solution in time. I need to act on the presence of the next smallest number to the right, and also act in the case there is no smaller number to the right.
I've tried thinking of dynamic programming solutions and data structures (specifically a stack), but I can't seem to keep correctness and O(n) time complexity both in check, one or the other seems to fail for me.
Any help?
You can think of using a stack data structure for this. I have implemented it in Java. The idea is push the index to pop and while the top index value in stack is greater than current index value of the array pop the stack and assign the value at current index to the poped index location.
// Java Implementation of the idea
import java.util.Arrays;
import java.util.Stack;
public class NextSmallest{
public static void main(String[] args) {
int [] A = {4, 5, 2, 6, 7, 1};
int [] ret = nextSmallest(A);
System.out.println(Arrays.toString(ret)); // prints [2, 2, 1, 1, 1, 0]
}
static int [] nextSmallest(int [] A) {
Stack<Integer> stack = new Stack<>();
int n = A.length;
int [] nextSmallestIndex = new int[n];
for(int i = 0; i < n; i++) {
while(!stack.isEmpty() && A[stack.peek()] > A[i]) {
nextSmallestIndex[stack.pop()] = A[i];
}
stack.push(i);
}
return nextSmallestIndex;
}
}
You can use this simple loop over all array elements and get index of numbers you want
var arr = [4, 5, 2, 6, 7, 1];
var object = {};
for (var i = 0; i < arr.length; i++) {
if (i > 0 && i < arr.length - 1 && arr[i] < arr[i - 1] && arr[i] < arr[i + 1]) {
object[i] = arr[i];
} else if (i >= arr.length - 1 && arr[i] < arr[i - 1]) {
object[i] = arr[i];
}
}
console.log(object);
The object for output represents the index of next smallest number and its value. So if you want the smallest value for 4 or 5, because their indexes are before 2, their next smallest number will be object[2] and also for 6 and 7.
Full code
var arr = [4, 5, 2, 7, 6, 1];
var object = {};
for (var i = 0; i < arr.length; i++) {
if (i > 0 && i < arr.length - 1 && arr[i] < arr[i - 1] && arr[i] < arr[i + 1]) {
object[i] = arr[i];
} else if (i >= arr.length - 1 && arr[i] < arr[i - 1]) {
object[i] = arr[i];
}
}
function getResult(inpArr, number, obj) {
var keys = Object.keys(obj);
var index = inpArr.findIndex(function(itm) {
return itm == number;
});
// the number is not in the array
if (index == -1) {
return null;
}
for (var i = 0; i < keys.length; i++) {
if (index == keys[i]) {
return null;
}
if (index < keys[i]) {
return obj[keys[i]];
}
}
}
console.log("Result for 4: ", getResult(arr, 4, object));
console.log("Result for 5: ", getResult(arr, 5, object));
console.log("Result for 6: ", getResult(arr, 6, object));
console.log("Result for 7: ", getResult(arr, 7, object));
console.log("Result for 1: ", getResult(arr, 1, object));
console.log("Result for 2: ", getResult(arr, 2, object));
How do you define your start point? If you know you want to start at element 3 and look from there on, or do you want to find a value, and start at whatever element that value is at and go from there? What happens if a lower value isn't found for the rest of the array?
In PHP just because I'm in the middle of a PHP project, assuming you know what element you want to start with in the array.
<?php
// our array of numbers
$array=array(4, 5, 2, 7, 6, 1);
// what index are we starting at?
$start=2;
// what index are we comparing to?
$counter=0;
// some output
print("First value is ".$array[$start]." at array element ".$start);
// while the initial value is less or equal to the compare value, AND
// the compare position is within the bounds of the array
// increment the counter - our comparison isn't lower
while((($start+$counter)<count($array))&&($array[($start)]<=$array[($start+$counter)])){
$counter++;
}
// did we make it through without exceeding bounds of array or not?
if(($start+$counter)<count($array)){
print("\nNext lower value is ".$array[($start+$counter)]." at array element ".($start+$counter));
}else{
print("\nEnd of array reached without finding lower value...");
}
print("\n");
?>
Find the below solution in O(n) way with optimized code in JavaScript
var arr = [4, 5, 2, 7, 6, 1, 3, 4];
function getNextSmallestValue(index){
var elemvalue = arr[index];
var minValue = elemvalue;
for(var i=index;i<arr.length;i++){
if(minValue> arr[i]){
minValue = arr[i];
}
if((minValue!==elemvalue && elemvalue<arr[i]) || i === arr.length-1){
return minValue;
}
}
}
console.log(getNextSmallestValue(0)); // 2
console.log(getNextSmallestValue(3)); // 1

Selection of maximum sub-array from the array

Given an array of length n, it is required to find the maximum sum of elements one can choose if it is not allowed to choose more than two consecutive elements of the array. For example;
n=5;
arr[5] = {10,3,5,7,3};
Output : 23
10+3+7+3=23
So I have written this code;
#include <stdio.h>
#include <stdlib.h>
int max=0;
void solve(int arr[],int ind,int sum,int n,int count)
{
if(ind==n){
if(sum>max)
max=sum;
}
else{
sum+=arr[ind];
if(ind==n-1)
solve(arr,ind+1,sum,n,1);
if(ind==n-2 && count>1)
solve(arr,ind+2,sum,n,1);
if(ind<n-1 && count<2){
count++;
solve(arr,ind+1,sum,n,count);
}
if(ind<n-2)
solve(arr,ind+2,sum,n,1);
if(ind<n-3)
solve(arr,ind+3,sum,n,1);
}
}
int main()
{
int n;
scanf("%d",&n);
int i=0,arr[n];
while(i<n){
scanf("%d",&arr[i]);
i++;
}
int count=1;
//going into all three possibilities
solve(arr,0,0,n,count);
solve(arr,1,0,n,count);
solve(arr,2,0,n,count);
printf("%d\n",max);
return 0;
}
This program produces the expected outputs for n<1000 but shows runtime error (SIGSEGV) for larger inputs. What may be the reason?
More effective solutions are also welcome.....
use dynamic programming
DP[i]: maximum from "i" index
there are 7 cases:
1- use the first and second elements
2- use the second and third elements
3- use the first and third elements
4- use only the first element
5- use only the second element
6- use only the third element
7- use none of the elements
int F(int[] a)
{
if (a.Length == 1)
{
return Max(a[0], 0);
}
int n = a.Length;
int[] DP = new int[n];
DP[n - 1] = Max(a[n - 1], 0);
DP[n - 2] = DP[n - 1] + Max(a[n - 2], 0);
for (int i = n - 3; i >= 0; i--)
{
DP[i] = Max(a[i], 0) + Max(a[i + 1], 0) + (i + 3 < n ? DP[i + 3] : 0);// first and second
DP[i] = Max(DP[i], Max(a[i + 1], 0) + Max(a[i + 2], 0) + (i + 4 < n ? DP[i + 4] : 0));// second and third
DP[i] = Max(DP[i], Max(a[i + 0], 0) + Max(a[i + 2], 0) + (i + 4 < n ? DP[i + 4] : 0));// first and third
DP[i] = Max(DP[i], Max(a[i + 0], 0) + (i + 2 < n ? DP[i + 2] : 0));// first
DP[i] = Max(DP[i], Max(a[i + 1], 0) + (i + 3 < n ? DP[i + 3] : 0));// second
DP[i] = Max(DP[i], Max(a[i + 2], 0) + (i + 4 < n ? DP[i + 4] : 0));// third
DP[i] = Max(DP[i], DP[i + 1]);// none
}
return DP[0];
}
example1:
int[] a = new int[] { 10, 3, 5, 7, 3 };
writer.WriteLine(F(a));
output:
23
example2:
int[] a = new int[] { 1, 5, 2, 6, 9, 8, 20, 12, 41, 3, 0, 9, 95, 6, 74, 85, 20, 14, 26, 35, 14, 72, 15 };
writer.WriteLine(F(a));
output:
496
Implementation in C
This problem has a fairly simple dynamic programming solution.
Each item in the array represents a binary choice: it can either be selected or not. But if two consecutive items are selected, then the next item cannot be selected. So for each item in the array we need to keep track of three sums
the best sum if the current item is not selected
the best sum if the current item is selected, and the previous item was not selected
the best sum if the current item is selected, and the previous item was selected
Here's the code:
#include <stdio.h>
#define max3(a) (a[0]>a[1] ? a[0]>a[2]?a[0]:a[2] : a[1]>a[2]?a[1]:a[2])
int main( void )
{
int array[] = { 10,3,7,55,60,62,4,2,5,42,8,9,12,5,1 };
int N = sizeof(array) / sizeof(array[0]);
int dp[N][3];
dp[0][0] = 0;
dp[0][1] = array[0];
dp[0][2] = 0;
for ( int i = 1; i < N; i++ )
{
dp[i][0] = max3(dp[i-1]);
dp[i][1] = dp[i-1][0] + array[i];
dp[i][2] = dp[i-1][1] + array[i];
}
printf( "%d\n", max3(dp[N-1]) );
}
The output of this program is 208. To understand how that was computed, take a look at the contents of the dp array:
Note that the correct path through the dp array is not known until the end. In this example, two endpoints have the same sum, so there are two paths through the array that give the same answer. The two paths represent these choices:
array: 10 3 7 55 60 62 4 2 5 42 8 9 12 5 1
red: 10 +7 +60+62 +2 +42+8 +12+5 = 208
blue: 10 +7 +60+62 +5+42 +9+12 +1 = 208

Resources