Given the time taken by n tasks. Find the minimum time needed to finish the tasks such that skipping of tasks is allowed, but can not skip two consecutive tasks.
Examples :
Input : arr[] = {10, 5, 7, 10}
Output : 12
We can skip first and last task and
finish these task in 12 min.
Input : arr[] = {10}
Output : 0
There is only one task and we can
skip it.
Input : arr[] = {10, 30}
Output : 10
Input : arr[] = {10, 5, 2, 4, 8, 6, 7, 10}
Output : 22
The given problem has the following recursive property.
Let minTime(i) be minimum time to finish till i’th task. It can be written as minimum of two values.
- Minimum time if i’th task is included in list, let this time be incl(i)
- Minimum time if i’th task is excluded from result, let this time be excl(i)
minTime(i) = min(excl(i), incl(i))
The result is minTime(n-1) if there are n tasks and indexes start from 0.
incl(i) can be written as below.
// There are two possibilities
// (a) Previous task is also included
// (b) Previous task is not included
incl(i) = min(incl(i-1), excl(i-1)) +
arr[i] // Since this is inclusive
// arr[i] must be included
excl(i) can be written as below.
// There is only one possibility (Previous task must be
// included as we can't skip consecutive tasks.
excl(i) = incl(i-1)
A simple solution is to make two tables incl[] and excl[] to store times for tasks. Finally, return a minimum of incl[n-1] and excl[n-1]. This solution requires O(n) time and O(n) space.
If we take a closer look, we can notice that we only need incl and excl of the previous job. So we can save space and solve the problem in O(n) time and O(1) space.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minTime( int arr[], int n)
{
if (n <= 0)
return 0;
int incl = arr[0];
int excl = 0;
for ( int i=1; i<n; i++)
{
int incl_new = arr[i] + min(excl, incl);
int excl_new = incl;
incl = incl_new;
excl = excl_new;
}
return min(incl, excl);
}
int main()
{
int arr1[] = {10, 5, 2, 7, 10};
int n1 = sizeof (arr1)/ sizeof (arr1[0]);
cout << minTime(arr1, n1) << endl;
int arr2[] = {10, 5, 7, 10};
int n2 = sizeof (arr2)/ sizeof (arr2[0]);
cout << minTime(arr2, n2) << endl;
int arr3[] = {10, 5, 2, 4, 8, 6, 7, 10};
int n3 = sizeof (arr3)/ sizeof (arr3[0]);
cout << minTime(arr3, n3) << endl;
return 0;
}
|
Java
import java.io.*;
class GFG {
static int minTime( int arr[], int n)
{
if (n <= 0 )
return 0 ;
int incl = arr[ 0 ];
int excl = 0 ;
for ( int i = 1 ; i < n; i++)
{
int incl_new = arr[i] + Math.min(excl,
incl);
int excl_new = incl;
incl = incl_new;
excl = excl_new;
}
return Math.min(incl, excl);
}
public static void main(String[] args)
{
int arr1[] = { 10 , 5 , 2 , 7 , 10 };
int n1 = arr1.length;
System.out.println(minTime(arr1, n1));
int arr2[] = { 10 , 5 , 7 , 10 };
int n2 = arr2.length;
System.out.println(minTime(arr2, n2));
int arr3[] = { 10 , 5 , 2 , 4 , 8 , 6 , 7 , 10 };
int n3 = arr3.length;
System.out.println(minTime(arr3, n3));
}
}
|
Python3
def minTime(arr, n):
if (n < = 0 ): return 0
incl = arr[ 0 ]
excl = 0
for i in range ( 1 , n):
incl_new = arr[i] + min (excl, incl)
excl_new = incl
incl = incl_new
excl = excl_new
return min (incl, excl)
arr1 = [ 10 , 5 , 2 , 7 , 10 ]
n1 = len (arr1)
print (minTime(arr1, n1))
arr2 = [ 10 , 5 , 7 , 10 ]
n2 = len (arr2)
print (minTime(arr2, n2))
arr3 = [ 10 , 5 , 2 , 4 , 8 , 6 , 7 , 10 ]
n3 = len (arr3)
print (minTime(arr3, n3))
|
C#
using System;
class GFG {
static int minTime( int []arr, int n)
{
if (n <= 0)
return 0;
int incl = arr[0];
int excl = 0;
for ( int i = 1; i < n; i++)
{
int incl_new = arr[i] + Math.Min(excl,
incl);
int excl_new = incl;
incl = incl_new;
excl = excl_new;
}
return Math.Min(incl, excl);
}
public static void Main()
{
int []arr1 = {10, 5, 2, 7, 10};
int n1 = arr1.Length;
Console.WriteLine(minTime(arr1, n1));
int []arr2 = {10, 5, 7, 10};
int n2 = arr2.Length;
Console.WriteLine(minTime(arr2, n2));
int []arr3 = {10, 5, 2, 4, 8, 6, 7, 10};
int n3 = arr3.Length;
Console.WriteLine(minTime(arr3, n3));
}
}
|
PHP
<?php
function minTime( $arr , $n )
{
if ( $n <= 0)
return 0;
$incl = $arr [0];
$excl = 0;
for ( $i = 1; $i < $n ; $i ++)
{
$incl_new = $arr [ $i ] + min( $excl , $incl );
$excl_new = $incl ;
$incl = $incl_new ;
$excl = $excl_new ;
}
return min( $incl , $excl );
}
$arr1 = array (10, 5, 2, 7, 10);
$n1 = sizeof( $arr1 );
echo minTime( $arr1 , $n1 ), "\n" ;
$arr2 = array (10, 5, 7, 10);
$n2 = sizeof( $arr2 );
echo minTime( $arr2 , $n2 ), "\n" ;
$arr3 = array (10, 5, 2, 4,
8, 6, 7, 10);
$n3 = sizeof( $arr3 );
echo minTime( $arr3 , $n3 );
?>
|
Javascript
<script>
function minTime(arr, n)
{
if (n <= 0)
return 0;
let incl = arr[0];
let excl = 0;
for (let i = 1; i < n; i++)
{
let incl_new = arr[i] + Math.min(excl,
incl);
let excl_new = incl;
incl = incl_new;
excl = excl_new;
}
return Math.min(incl, excl);
}
let arr1 = [10, 5, 2, 7, 10];
let n1 = arr1.length;
document.write(minTime(arr1, n1) + "<br/>" );
let arr2 = [10, 5, 7, 10];
let n2 = arr2.length;
document.write(minTime(arr2, n2) + "<br/>" );
let arr3 = [10, 5, 2, 4, 8, 6, 7, 10];
let n3 = arr3.length;
document.write(minTime(arr3, n3) + "<br/>" );
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(1)
Related Problems:
Find minimum time to finish all jobs with given constraints
Maximum sum such that no two elements are adjacent.
This article is contributed by Arnab Dutta. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above