There are n houses build in a line, each of which contains some value in it. A thief is going to steal the maximal value of these houses, but he can’t steal in two adjacent houses because the owner of the stolen houses will tell his two neighbors left and right side. What is the maximum stolen value?
Examples:
Input: hval[] = {6, 7, 1, 3, 8, 2, 4}
Output: 19
Explanation: The thief will steal 6, 1, 8 and 4 from the house.
Input: hval[] = {5, 3, 4, 11, 2}
Output: 16
Explanation: Thief will steal 5 and 11
Naive Approach: Given an array, the solution is to find the maximum sum subsequence where no two selected elements are adjacent. So the approach to the problem is a recursive solution.
So there are two cases:
- If an element is selected then the next element cannot be selected.
- if an element is not selected then the next element can be selected.
Implementation of recursion approach:
C++
#include <iostream>
using namespace std;
int maxLoot( int * hval, int n)
{
if (n < 0) {
return 0;
}
if (n == 0) {
return hval[0];
}
int pick = hval[n] + maxLoot(hval, n - 2);
int notPick = maxLoot(hval, n - 1);
return max(pick, notPick);
}
int main()
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof (hval) / sizeof (hval[0]);
cout << "Maximum loot possible : "
<< maxLoot(hval, n - 1);
return 0;
}
|
C
#include <stdio.h>
int max( int num1, int num2)
{
return (num1 > num2) ? num1 : num2;
}
int maxLoot( int * hval, int n)
{
if (n < 0)
return 0;
if (n == 0)
return hval[0];
int pick = hval[n] + maxLoot(hval, n - 2);
int notPick = maxLoot(hval, n - 1);
return max(pick, notPick);
}
int main()
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof (hval) / sizeof (hval[0]);
printf ( "Maximum loot possible : %d " ,
maxLoot(hval, n - 1));
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int maxLoot( int hval[], int n)
{
if (n < 0 ) {
return 0 ;
}
if (n == 0 ) {
return hval[ 0 ];
}
int pick = hval[n] + maxLoot(hval, n - 2 );
int notPick = maxLoot(hval, n - 1 );
return Math.max(pick, notPick);
}
public static void main(String[] args)
{
int hval[] = { 6 , 7 , 1 , 3 , 8 , 2 , 4 };
int n = hval.length;
System.out.println( "Maximum loot value : "
+ maxLoot(hval, n- 1 ));
}
}
|
Python3
def maxLoot(hval,n):
if (n < 0 ):
return 0
if (n = = 0 ):
return hval[ 0 ]
pick = hval[n] + maxLoot(hval, n - 2 )
notPick = maxLoot(hval, n - 1 )
return max (pick, notPick)
hval = [ 6 , 7 , 1 , 3 , 8 , 2 , 4 ]
n = len (hval)
print ( "Maximum loot possible : " ,maxLoot(hval, n - 1 ));
|
C#
using System;
public class GFG {
static int maxLoot( int [] hval, int n)
{
if (n < 0) {
return 0;
}
if (n == 0) {
return hval[0];
}
int pick = hval[n] + maxLoot(hval, n - 2);
int notPick = maxLoot(hval, n - 1);
return Math.Max(pick, notPick);
}
static public void Main()
{
int [] hval = { 6, 7, 1, 3, 8, 2, 4 };
int n = hval.Length;
Console.WriteLine( "Maximum loot value : "
+ maxLoot(hval, n - 1));
}
}
|
Javascript
<script>
function maxLoot(hval,n)
{
if (n < 0) {
return 0;
}
if (n == 0) {
return hval[0];
}
let pick = hval[n] + maxLoot(hval, n - 2);
let notPick = maxLoot(hval, n - 1);
return Math.max(pick, notPick);
}
let hval = [ 6, 7, 1, 3, 8, 2, 4 ];
let n = hval.length;
document.write( "Maximum loot possible : " ,maxLoot(hval, n - 1));
</script>
|
OutputMaximum loot possible : 19
Complexity Analysis
Time Complexity: O(2N). Every element has 2 choices to pick and not pick
Space Complexity: O(2N). A recursion stack space is required of size 2n, so space complexity is O(2N).
Method 2: Dynamic Programming : Top Down Approach
So the recursive solution can easily be devised. The sub-problems can be stored thus reducing the complexity and converting the recursive solution to a Dynamic programming problem.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int maxLoot( int *hval, int n, vector< int > &dp){
if (n < 0){
return 0 ;
}
if (n == 0){
return hval[0] ;
}
if (dp[n] != -1 ){
return dp[n] ;
}
int pick = hval[n] + maxLoot(hval, n-2, dp) ;
int notPick = maxLoot(hval, n-1, dp) ;
return dp[n] = max(pick, notPick) ;
}
int main()
{
int hval[] = {6, 7, 1, 3, 8, 2, 4};
int n = sizeof (hval)/ sizeof (hval[0]);
vector< int > dp(n+1, -1) ;
cout << "Maximum loot possible : "
<< maxLoot(hval, n-1, dp);
return 0;
}
|
Java
import java.io.*;
import java.util.Arrays;
class GFG {
static int maxLoot( int hval[], int n, int dp[])
{
if (n < 0 ) {
return 0 ;
}
if (n == 0 ) {
return hval[ 0 ];
}
if (dp[n] != - 1 ) {
return dp[n];
}
int pick = hval[n] + maxLoot(hval, n - 2 , dp);
int notPick = maxLoot(hval, n - 1 , dp);
return dp[n] = Math.max(pick, notPick);
}
public static void main(String[] args)
{
int hval[] = { 6 , 7 , 1 , 3 , 8 , 2 , 4 };
int n = hval.length;
int dp[] = new int [n + 1 ];
Arrays.fill(dp, - 1 );
System.out.println( "Maximum loot value : "
+ maxLoot(hval, n - 1 , dp));
}
}
|
Python3
def maxLoot(hval,n,dp):
if (n < 0 ):
return 0
if (n = = 0 ):
return hval[ 0 ]
if (dp[n] ! = - 1 ):
return dp[n]
pick = hval[n] + maxLoot(hval, n - 2 , dp)
notPick = maxLoot(hval, n - 1 , dp)
dp[n] = max (pick, notPick)
return dp[n]
hval = [ 6 , 7 , 1 , 3 , 8 , 2 , 4 ]
n = len (hval)
dp = [ - 1 for i in range (n + 1 )]
print ( "Maximum loot possible : " + str (maxLoot(hval, n - 1 , dp)))
|
Javascript
<script>
function maxLoot(hval,n,dp){
if (n < 0){
return 0 ;
}
if (n == 0){
return hval[0] ;
}
if (dp[n] != -1 ){
return dp[n] ;
}
let pick = hval[n] + maxLoot(hval, n-2, dp) ;
let notPick = maxLoot(hval, n-1, dp) ;
return dp[n] = Math.max(pick, notPick) ;
}
let hval = [6, 7, 1, 3, 8, 2, 4];
let n = hval.length;
let dp = new Array(n+1).fill(-1) ;
document.write( "Maximum loot possible : " ,maxLoot(hval, n-1, dp), "</br>" );
</script>
|
OutputMaximum loot possible : 19
Complexity Analysis:
Time Complexity: O(n) . Only one traversal of original array is needed. So the time complexity is O(n)
Space Complexity: O(n). Recursive stack space is required of size n, so space complexity is O(n).
Method 3: Dynamic Programming : Bottom Up Approach
So the recursive solution can easily be devised. The sub-problems can be stored thus reducing the complexity and converting the recursive solution to a Dynamic programming problem.
Algorithm:
- Create an extra space dp, DP array to store the sub-problems.
- Tackle some basic cases, if the length of the array is 0, print 0, if the length of the array is 1, print the first element, if the length of the array is 2, print maximum of two elements.
- Update dp[0] as array[0] and dp[1] as maximum of array[0] and array[1]
- Traverse the array from the second element (2nd index) to the end of array.
- For every index, update dp[i] as maximum of dp[i-2] + array[i] and dp[i-1], this step defines the two cases, if an element is selected then the previous element cannot be selected and if an element is not selected then the previous element can be selected.
- Print the value dp[n-1]
Implementation:
C++
#include <iostream>
using namespace std;
int maxLoot( int * hval, int n)
{
if (n == 0)
return 0;
if (n == 1)
return hval[0];
if (n == 2)
return max(hval[0], hval[1]);
int dp[n];
dp[0] = hval[0];
dp[1] = max(hval[0], hval[1]);
for ( int i = 2; i < n; i++)
dp[i] = max(hval[i] + dp[i - 2], dp[i - 1]);
return dp[n - 1];
}
int main()
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof (hval) / sizeof (hval[0]);
cout << "Maximum loot possible : " << maxLoot(hval, n);
return 0;
}
|
C
#include <stdio.h>
int max( int num1, int num2)
{
return (num1 > num2) ? num1 : num2;
}
int maxLoot( int * hval, int n)
{
if (n == 0)
return 0;
if (n == 1)
return hval[0];
if (n == 2)
return max(hval[0], hval[1]);
int dp[n];
dp[0] = hval[0];
dp[1] = max(hval[0], hval[1]);
for ( int i = 2; i < n; i++)
dp[i] = max(hval[i] + dp[i - 2], dp[i - 1]);
return dp[n - 1];
}
int main()
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof (hval) / sizeof (hval[0]);
printf ( "Maximum loot possible : %d" , maxLoot(hval, n));
return 0;
}
|
Java
import java.io.*;
class GFG {
static int maxLoot( int hval[], int n)
{
if (n == 0 )
return 0 ;
if (n == 1 )
return hval[ 0 ];
if (n == 2 )
return Math.max(hval[ 0 ], hval[ 1 ]);
int [] dp = new int [n];
dp[ 0 ] = hval[ 0 ];
dp[ 1 ] = Math.max(hval[ 0 ], hval[ 1 ]);
for ( int i = 2 ; i < n; i++)
dp[i]
= Math.max(hval[i] + dp[i - 2 ], dp[i - 1 ]);
return dp[n - 1 ];
}
public static void main(String[] args)
{
int hval[] = { 6 , 7 , 1 , 3 , 8 , 2 , 4 };
int n = hval.length;
System.out.println( "Maximum loot value : " + maxLoot(hval, n));
}
}
|
Python3
def maximize_loot(hval, n):
if n = = 0 :
return 0
if n = = 1 :
return hval[ 0 ]
if n = = 2 :
return max (hval[ 0 ], hval[ 1 ])
dp = [ 0 ] * n
dp[ 0 ] = hval[ 0 ]
dp[ 1 ] = max (hval[ 0 ], hval[ 1 ])
for i in range ( 2 , n):
dp[i] = max (hval[i] + dp[i - 2 ], dp[i - 1 ])
return dp[ - 1 ]
def main():
hval = [ 6 , 7 , 1 , 3 , 8 , 2 , 4 ]
n = len (hval)
print ( "Maximum loot value : {}" .
format (maximize_loot(hval, n)))
if __name__ = = '__main__' :
main()
|
C#
using System;
class GFG
{
static int maxLoot( int []hval, int n)
{
if (n == 0)
return 0;
if (n == 1)
return hval[0];
if (n == 2)
return Math.Max(hval[0], hval[1]);
int [] dp = new int [n];
dp[0] = hval[0];
dp[1] = Math.Max(hval[0], hval[1]);
for ( int i = 2; i<n; i++)
dp[i] = Math.Max(hval[i]+dp[i-2], dp[i-1]);
return dp[n-1];
}
public static void Main ()
{
int []hval = {6, 7, 1, 3, 8, 2, 4};
int n = hval.Length;
Console.WriteLine( "Maximum loot value : " +
maxLoot(hval, n));
}
}
|
PHP
<?php
function maxLoot( $hval , $n )
{
if ( $n == 0)
return 0;
if ( $n == 1)
return $hval [0];
if ( $n == 2)
return max( $hval [0],
$hval [1]);
$dp = array ();
$dp [0] = $hval [0];
$dp [1] = max( $hval [0],
$hval [1]);
for ( $i = 2; $i < $n ; $i ++)
$dp [ $i ] = max( $hval [ $i ] +
$dp [ $i - 2],
$dp [ $i - 1]);
return $dp [ $n - 1];
}
$hval = array (6, 7, 1,
3, 8, 2, 4);
$n = sizeof( $hval );
echo "Maximum loot possible : " ,
maxLoot( $hval , $n );
?>
|
Javascript
<script>
function maxLoot(hval, n)
{
if (n == 0)
return 0;
if (n == 1)
return hval[0];
if (n == 2)
return Math.max(hval[0], hval[1]);
let dp = new Array(n);
dp[0] = hval[0];
dp[1] = Math.max(hval[0], hval[1]);
for (let i = 2; i<n; i++)
dp[i] = Math.max(hval[i]+dp[i-2], dp[i-1]);
return dp[n-1];
}
let hval = [6, 7, 1, 3, 8, 2, 4];
let n = hval.length;
document.write(
"Maximum loot value : " + maxLoot(hval, n)
);
</script>
|
OutputMaximum loot possible : 19
Complexity Analysis:
- Time Complexity:
.
Only one traversal of original array is needed. So the time complexity is O(n) - Space Complexity:
.
An array is required of size n, so space complexity is O(n).
Efficient Approach: By carefully observing the DP array, it can be seen that the values of previous two indices matter while calculating the value for an index. To replace the total DP array by two variables.
Algorithm:
- Tackle some basic cases, if the length of the array is 0, print 0, if the length of the array is 1, print the first element, if the length of the array is 2, print maximum of two elements.
- Create two variables value1 and value2 value1 as array[0] and value2 as maximum of array[0] and array[1] and a variable max_val to store the answer
- Traverse the array from the second element (2nd index) to the end of array.
- For every index, update max_val as maximum of value1 + array[i] and value2, this step defines the two cases, if an element is selected then the previous element cannot be selected and if an element is not selected then the previous element can be selected.
- For every index, Update value1 = value2 and value2 = max_val
- Print the value of max_val
Implementation:
C++
#include <iostream>
using namespace std;
int maxLoot( int * hval, int n)
{
if (n == 0)
return 0;
int value1 = hval[0];
if (n == 1)
return value1;
int value2 = max(hval[0], hval[1]);
if (n == 2)
return value2;
int max_val;
for ( int i = 2; i < n; i++) {
max_val = max(hval[i] + value1, value2);
value1 = value2;
value2 = max_val;
}
return max_val;
}
int main()
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof (hval) / sizeof (hval[0]);
cout << "Maximum loot possible : " << maxLoot(hval, n);
return 0;
}
|
C
#include <stdio.h>
int max( int num1, int num2)
{
return (num1 > num2) ? num1 : num2;
}
int maxLoot( int * hval, int n)
{
if (n == 0)
return 0;
int value1 = hval[0];
if (n == 1)
return value1;
int value2 = max(hval[0], hval[1]);
if (n == 2)
return value2;
int max_val;
for ( int i = 2; i < n; i++) {
max_val = max(hval[i] + value1, value2);
value1 = value2;
value2 = max_val;
}
return max_val;
}
int main()
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof (hval) / sizeof (hval[0]);
printf ( "Maximum loot possible : %d" , maxLoot(hval, n));
return 0;
}
|
Java
import java.io.*;
class GFG {
static int maxLoot( int hval[], int n)
{
if (n == 0 )
return 0 ;
int value1 = hval[ 0 ];
if (n == 1 )
return value1;
int value2 = Math.max(hval[ 0 ], hval[ 1 ]);
if (n == 2 )
return value2;
int max_val = 0 ;
for ( int i = 2 ; i < n; i++) {
max_val = Math.max(hval[i] + value1, value2);
value1 = value2;
value2 = max_val;
}
return max_val;
}
public static void main(String[] args)
{
int hval[] = { 6 , 7 , 1 , 3 , 8 , 2 , 4 };
int n = hval.length;
System.out.println( "Maximum loot value : "
+ maxLoot(hval, n));
}
}
|
Python3
def maximize_loot(hval, n):
if n = = 0 :
return 0
value1 = hval[ 0 ]
if n = = 1 :
return value1
value2 = max (hval[ 0 ], hval[ 1 ])
if n = = 2 :
return value2
max_val = None
for i in range ( 2 , n):
max_val = max (hval[i] + value1, value2)
value1 = value2
value2 = max_val
return max_val
def main():
hval = [ 6 , 7 , 1 , 3 , 8 , 2 , 4 ]
n = len (hval)
print ( "Maximum loot value : {}" . format (maximize_loot(hval, n)))
if __name__ = = '__main__' :
main()
|
C#
using System;
public class GFG
{
static int maxLoot( int []hval, int n)
{
if (n == 0)
return 0;
int value1 = hval[0];
if (n == 1)
return value1;
int value2 = Math.Max(hval[0], hval[1]);
if (n == 2)
return value2;
int max_val = 0;
for ( int i = 2; i < n; i++)
{
max_val = Math.Max(hval[i] + value1, value2);
value1 = value2;
value2 = max_val;
}
return max_val;
}
public static void Main ()
{
int []hval = {6, 7, 1, 3, 8, 2, 4};
int n = hval.Length;
Console.WriteLine( "Maximum loot value : " +
maxLoot(hval, n));
}
}
|
PHP
<?php
function maxLoot( $hval , $n )
{
if ( $n == 0)
return 0;
$value1 = $hval [0];
if ( $n == 1)
return $value1 ;
$value2 = max( $hval [0],
$hval [1]);
if ( $n == 2)
return $value2 ;
$max_val ;
for ( $i = 2; $i < $n ; $i ++)
{
$max_val = max( $hval [ $i ] +
$value1 , $value2 );
$value1 = $value2 ;
$value2 = $max_val ;
}
return $max_val ;
}
$hval = array (6, 7, 1, 3, 8, 2, 4);
$n = sizeof( $hval );
echo "Maximum loot value : " ,
maxLoot( $hval , $n );
?>
|
Javascript
<script>
function maxLoot(hval, n)
{
if (n == 0)
return 0;
let value1 = hval[0];
if (n == 1)
return value1;
let value2 = Math.max(hval[0], hval[1]);
if (n == 2)
return value2;
let max_val = 0;
for (let i = 2; i < n; i++)
{
max_val = Math.max(hval[i] +
value1, value2);
value1 = value2;
value2 = max_val;
}
return max_val;
}
let hval = [6, 7, 1, 3, 8, 2, 4];
let n = hval.length;
document.write( "Maximum loot value : "
+ maxLoot(hval, n));
</script>
|
OutputMaximum loot possible : 19
Complexity Analysis:
- Time Complexity:
, Only one traversal of original array is needed. So the time complexity is O(n). - Auxiliary Space:
, No extra space is required so the space complexity is constant.
This article is contributed by Atul Kumar. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.