给定n个任务花费的时间。找到完成任务所需的最短时间,以允许跳过任务,但不能跳过两个连续的任务。
例子 :
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
预期时间复杂度为O(n),额外空间为O(1)。
给定的问题具有以下递归属性。
让minTime(i)是完成第i个任务的最短时间。它可以写为至少两个值。
- 如果列表中包含第i个任务的最短时间,则使该时间为incl(i)
- 如果从结果中排除第i个任务的最短时间,则使此时间为exl(i)
minTime(i) = min(excl(i), incl(i))
如果有n个任务并且索引从0开始,则结果为minTime(n-1) 。
incl(i)可以写成如下形式。
// 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)可以写成如下形式。
// There is only one possibility (Previous task must be
// included as we can't skip consecutive tasks.
excl(i) = incl(i-1)
一个简单的解决方案是使两个表包括incl []和excl []以存储任务的时间。最后返回incl [n-1]和excl [n-1]的最小值。该解决方案需要O(n)时间和O(n)空间。
如果我们仔细观察,会发现我们只需要上一份工作的incl和excl。因此,我们可以节省空间并解决O(n)时间和O(1)空间中的问题。以下是该想法的C++实现。
C++
// C++ program to find minimum time to finish tasks
// such that no two consecutive tasks are skipped.
#include
using namespace std;
// arr[] represents time taken by n given tasks
int minTime(int arr[], int n)
{
// Corner Cases
if (n <= 0)
return 0;
// Initialize value for the case when there
// is only one task in task list.
int incl = arr[0]; // First task is included
int excl = 0; // First task is exluded
// Process remaining n-1 tasks
for (int i=1; i
Java
// Java program to find minimum time to
// finish tasks such that no two
// consecutive tasks are skipped.
import java.io.*;
class GFG {
// arr[] represents time taken by n
// given tasks
static int minTime(int arr[], int n)
{
// Corner Cases
if (n <= 0)
return 0;
// Initialize value for the case
// when there is only one task in
// task list.
// First task is included
int incl = arr[0];
// First task is exluded
int excl = 0;
// Process remaining n-1 tasks
for (int i = 1; i < n; i++)
{
// Time taken if current task is
// included. There are two
// possibilities
// (a) Previous task is also included
// (b) Previous task is not included
int incl_new = arr[i] + Math.min(excl,
incl);
// Time taken when current task is not
// included. There is only one
// possibility that previous task is
// also included.
int excl_new = incl;
// Update incl and excl for next
// iteration
incl = incl_new;
excl = excl_new;
}
// Return maximum of two values for
// last task
return Math.min(incl, excl);
}
// Driver code
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));
}
}
// This code is contributed by Prerna Saini
Python3
# Python3 program to find minimum
# time to finish tasks such that no
# two consecutive tasks are skipped.
# arr[] represents time
# taken by n given tasks
def minTime(arr, n):
# Corner Cases
if (n <= 0): return 0
# Initialize value for the
# case when there is only
# one task in task list.
incl = arr[0] # First task is included
excl = 0 # First task is exluded
# Process remaining n-1 tasks
for i in range(1, n):
# Time taken if current task is included
# There are two possibilities
# (a) Previous task is also included
# (b) Previous task is not included
incl_new = arr[i] + min(excl, incl)
# Time taken when current task is not
# included. There is only one possibility
# that previous task is also included.
excl_new = incl
# Update incl and excl for next iteration
incl = incl_new
excl = excl_new
# Return maximum of two values for last task
return min(incl, excl)
# Driver code
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))
# This code is contributed by Anant Agarwal.
C#
// C# program to find minimum time to
// finish tasks such that no two
// consecutive tasks are skipped.
using System;
class GFG {
// arr[] represents time taken by n
// given tasks
static int minTime(int []arr, int n)
{
// Corner Cases
if (n <= 0)
return 0;
// Initialize value for the case
// when there is only one task in
// task list.
// First task is included
int incl = arr[0];
// First task is exluded
int excl = 0;
// Process remaining n-1 tasks
for (int i = 1; i < n; i++)
{
// Time taken if current task is
// included. There are two
// possibilities
// (a) Previous task is also included
// (b) Previous task is not included
int incl_new = arr[i] + Math.Min(excl,
incl);
// Time taken when current task is not
// included. There is only one
// possibility that previous task is
// also included.
int excl_new = incl;
// Update incl and excl for next
// iteration
incl = incl_new;
excl = excl_new;
}
// Return maximum of two values for
// last task
return Math.Min(incl, excl);
}
// Driver code
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));
}
}
// This code is contributed by Anant Agarwal.
PHP
Javascript
输出 :
12
12
22