Skip to content
Related Articles
Open in App
Not now

Related Articles

Maximum path sum for each position with jumps under divisibility condition

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 12 Dec, 2022
Improve Article
Save Article

Given an array of n positive integers. Initially we are at first position. We can jump to position y (1 <= y <= n) from position x (1 <= x <= n) if x divides y and x < y. The task is to print maximum sum path ending at every position x.

Note : Since first element is at position 1, we can jump to any position from here as 1 divides all other position numbers.

Examples : 

Input :  arr[] = {2, 3, 1, 4, 6, 5}
Output : 2 5 3 9 8 10
Explanation:
Maximum sum path ending with position 1 is 2.
For position 1, last position to visit is 1 only.
So maximum sum for position 1 = 2.

Maximum sum path ending with position 2 is 5.
For position 2, path can be jump from position 1 
to 2 as 1 divides 2.
So maximum sum for position 2 = 2 + 3 = 5.

For position 3, path can be jump from position 1 
to 3 as 1 divides 3.
So maximum sum for position 3 = 2 + 1 = 3.

For position 4, path can be jump from position 1
to 2 and 2 to 4.
So maximum sum for position 4 = 2 + 3 + 4 = 9.

For position 5, path can be jump from position 1 
to 5.
So maximum sum for position 5 = 2 + 6 = 8.

For position 6, path can be jump from position 
1 to 2 and 2 to 6 or 1 to 3 and 3 to 6.
But path 1 -> 2 -> 6 gives maximum sum for
position 6 = 2 + 3 + 5 = 10.

Approach:

The idea is to use Dynamic Programming to solve this problem. 

Create an 1-D array dp[] where each element dp[i] 
stores maximum sum path ending at index i (or 
position x where x = i+1) with divisible jumps.

The recurrence relation for dp[i] can be defined as:

dp[i] = max(dp[i], dp[divisor of i+1] + arr[i]) 

To find all the divisor of i+1, move from 1 
divisor to sqrt(i+1).

Below is the implementation of this approach:  

C++




// C++ program to print maximum
// path sum ending with
// each position x such that all
// path step positions
// divide x.
#include <bits/stdc++.h>
using namespace std;
 
void printMaxSum(int arr[], int n)
{
     
    // Create an array such that dp[i]
    // stores maximum
    // path sum ending with i.
    int dp[n];
    memset(dp, 0, sizeof dp);
 
    // Calculating maximum sum path
    // for each element.
    for (int i = 0; i < n; i++) {
        dp[i] = arr[i];
 
        // Finding previous step for arr[i]
        // Moving from 1 to sqrt(i+1) since all the
        // divisors are present from sqrt(i+1).
        int maxi = 0;
        for (int j = 1; j <= sqrt(i + 1); j++) {
            // Checking if j is divisor of i+1.
            if (((i + 1) % j == 0) && (i + 1) != j) {
                // Checking which divisor will provide
                // greater value.
                if (dp[j - 1] > maxi)
                    maxi = dp[j - 1];
                if (dp[(i + 1) / j - 1] > maxi && j != 1)
                    maxi = dp[(i + 1) / j - 1];
            }
        }
 
        dp[i] += maxi;
    }
 
    // Printing the answer (Maximum path sum ending
    // with every position i+1.
    for (int i = 0; i < n; i++)
        cout << dp[i] << " ";
}
 
// Driven Program
int main()
{
    int arr[] = { 2, 3, 1, 4, 6, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    printMaxSum(arr, n);
 
    return 0;
}

Java




// Java program to print maximum path
// sum ending with each position x such
// that all path step positions divide x.
import java.util.*;
 
class GFG {
 
    static void printMaxSum(int arr[], int n)
    {
        // Create an array such that dp[i]
        // stores maximum path sum ending with i.
        int dp[] = new int[n];
        Arrays.fill(dp, 0);
 
        // Calculating maximum sum
        // path for each element.
        for (int i = 0; i < n; i++) {
            dp[i] = arr[i];
 
            // Finding previous step for arr[i]
            // Moving from 1 to sqrt(i+1) since all the
            // divisors are present from sqrt(i+1).
            int maxi = 0;
            for (int j = 1; j <= Math.sqrt(i + 1); j++) {
                 
                // Checking if j is divisor of i+1.
                if (((i + 1) % j == 0) && (i + 1) != j) {
                     
                    // Checking which divisor will
                    // provide greater value.
                    if (dp[j - 1] > maxi)
                        maxi = dp[j - 1];
                    if (dp[(i + 1) / j - 1] > maxi && j != 1)
                        maxi = dp[(i + 1) / j - 1];
                }
            }
 
            dp[i] += maxi;
        }
 
        // Printing the answer (Maximum path sum
        // ending with every position i+1.)
        for (int i = 0; i < n; i++)
            System.out.print(dp[i] + " ");
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 2, 3, 1, 4, 6, 5 };
        int n = arr.length;
         
        // Function calling
        printMaxSum(arr, n);
    }
}
 
// This code is contributed by Anant Agarwal.

Python3




# Python3 program to print maximum
# path sum ending with each position
# x such that all path step positions
# divide x.
 
def printMaxSum(arr, n):
     
    # Create an array such that dp[i]
    # stores maximum path sum ending with i.
    dp = [0 for i in range(n)]
 
    # Calculating maximum sum path
    # for each element.
    for i in range(n):
        dp[i] = arr[i]
 
        # Finding previous step for arr[i]
        # Moving from 1 to sqrt(i + 1) since all the
        # divisors are present from sqrt(i + 1).
        maxi = 0
        for j in range(1, int((i + 1) ** 0.5) + 1):
 
            # Checking if j is divisor of i + 1.
            if ((i + 1) % j == 0 and (i + 1) != j):
 
                # Checking which divisor will provide
                # greater value.
                if (dp[j - 1] > maxi):
                    maxi = dp[j - 1]
                if (dp[(i + 1) // j - 1] > maxi and j != 1):
                    maxi = dp[(i + 1) // j - 1]
 
        dp[i] += maxi
 
    # Printing the answer
    # (Maximum path sum ending
    # with every position i + 1).
    for i in range(n):
        print(dp[i], end = ' ')
 
# Driver Program
arr = [2, 3, 1, 4, 6, 5]
n = len(arr)
printMaxSum(arr, n)
 
# This code is contributed by Soumen Ghosh.

C#




// C# program to print maximum path
// sum ending with each position x such
// that all path step positions divide x.
using System;
 
class GFG {
 
    static void printMaxSum(int[] arr, int n)
    {
        // Create an array such that dp[i]
        // stores maximum path sum ending with i.
        int[] dp = new int[n];
 
        // Calculating maximum sum
        // path for each element.
        for (int i = 0; i < n; i++) {
            dp[i] = arr[i];
 
            // Finding previous step for arr[i]
            // Moving from 1 to sqrt(i+1) since all the
            // divisors are present from sqrt(i+1).
            int maxi = 0;
            for (int j = 1; j <= Math.Sqrt(i + 1); j++)
            {
                // Checking if j is divisor of i+1.
                if (((i + 1) % j == 0) && (i + 1) != j)
                {
                    // Checking which divisor will
                    // provide greater value.
                    if (dp[j - 1] > maxi)
                        maxi = dp[j - 1];
                    if (dp[(i + 1) / j - 1] > maxi && j != 1)
                        maxi = dp[(i + 1) / j - 1];
                }
            }
 
            dp[i] += maxi;
        }
 
        // Printing the answer (Maximum path sum ending
        // with every position i+1.)
        for (int i = 0; i < n; i++)
            Console.Write(dp[i] + " ");
    }
 
    // Driver code
    public static void Main()
    {
        int[] arr = { 2, 3, 1, 4, 6, 5 };
        int n = arr.Length;
         
        // Function calling
        printMaxSum(arr, n);
    }
}
 
// This code is contributed by vt_m.

PHP




<?php
// PHP program to print maximum path sum ending with
// each position x such that all path step positions
// divide x.
 
function printMaxSum($arr, $n)
{
    // Create an array such that dp[i] stores maximum
    // path sum ending with i.
    $dp = array() ;
 
    // Calculating maximum sum path for each element.
    for ($i = 0; $i < $n; $i++) {
        $dp[$i] = $arr[$i];
 
        // Finding previous step for arr[i]
        // Moving from 1 to sqrt(i+1) since all the
        // divisors are present from sqrt(i+1).
        $maxi = 0;
        for ($j = 1; $j <= sqrt($i + 1); $j++) {
            // Checking if j is divisor of i+1.
            if ((($i + 1) % $j == 0) && ($i + 1) != $j) {
                // Checking which divisor will provide
                // greater value.
                if ($dp[$j - 1] > $maxi)
                    $maxi = $dp[$j - 1];
                if ($dp[($i + 1) / $j - 1] > $maxi && $j != 1)
                    $maxi = $dp[($i + 1) / $j - 1];
            }
        }
 
        $dp[$i] += $maxi;
    }
 
    // Printing the answer (Maximum path sum ending
    // with every position i+1.
    for ($i = 0; $i < $n; $i++)
        echo $dp[$i] , " " ;
}
 
// Driven Program
$arr = array(2, 3, 1, 4, 6, 5 );
$n = sizeof($arr);
 
printMaxSum($arr, $n);
 
// This code is contributed by Ryuga
?>

Javascript




<script>
    // Javascript program to print maximum path
    // sum ending with each position x such
    // that all path step positions divide x.
     
    function printMaxSum(arr, n)
    {
        // Create an array such that dp[i]
        // stores maximum path sum ending with i.
        let dp = new Array(n);
        dp.fill(0);
  
        // Calculating maximum sum
        // path for each element.
        for (let i = 0; i < n; i++) {
            dp[i] = arr[i];
  
            // Finding previous step for arr[i]
            // Moving from 1 to sqrt(i+1) since all the
            // divisors are present from sqrt(i+1).
            let maxi = 0;
            for (let j = 1; j <= Math.sqrt(i + 1); j++)
            {
                // Checking if j is divisor of i+1.
                if (((i + 1) % j == 0) && (i + 1) != j)
                {
                    // Checking which divisor will
                    // provide greater value.
                    if (dp[j - 1] > maxi)
                        maxi = dp[j - 1];
                    if (dp[parseInt((i + 1) / j, 10) - 1] > maxi && j != 1)
                        maxi = dp[parseInt((i + 1) / j, 10) - 1];
                }
            }
  
            dp[i] += maxi;
        }
  
        // Printing the answer (Maximum path sum ending
        // with every position i+1.)
        for (let i = 0; i < n; i++)
            document.write(dp[i] + " ");
    }
     
    let arr = [ 2, 3, 1, 4, 6, 5 ];
    let n = arr.length;
 
    // Function calling
    printMaxSum(arr, n);
 
</script>

Output

2 5 3 9 8 10 

Time Complexity: O(n*sqrt(n)).
Auxiliary Space: O(n)

This article is contributed by Anuj Chauhan. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!