📌  相关文章
📜  最短时间完成任务而无需连续跳过两个

📅  最后修改于: 2021-04-23 16:10:17             🧑  作者: Mango

给定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个任务的最短时间。它可以写为至少两个值。

  1. 如果列表中包含第i个任务的最短时间,则使该时间为incl(i)
  2. 如果从结果中排除第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