📜  不执行任务的最少天数

📅  最后修改于: 2022-05-13 01:56:04.681000             🧑  作者: Mango

不执行任务的最少天数

给定一个由长度为 N 的值 (0, 1, 2, 3) 组成的数组arr[] ,表示可以在任何 ith 天完成的工作类型,这样任务要么属于A 类型,要么属于 B 类型。数组中的每个值定义为:
0 – 没有可用的任务。
1 – B 类任务可用。
2 – A 类任务可用。
3 – 任务 A 和任务 B 都可用。

如果连续两天无法完成同一类型的任务,则任务是尽量减少不执行任务的天数。

例子:

天真的方法:这个问题可以通过使用递归来解决。请按照以下步骤解决给定的问题。

  • 声明一个变量说 count = 0,以存储答案。
  • 如果 arr[i]=0,没有任务,所以什么都不做,增加计数。
  • 如果 arr[i]=1,只有任务 B 可用,如果最后一天的任务是 B,则什么都不做,增加计数,否则执行任务 B。
  • 如果 arr[i]=2,只有任务 A 可用,如果最后一天的任务是 A,则什么都不做,增加计数,否则执行任务 A。
  • 如果arr[i]=3,并且最后一天的任务是A,那么执行任务B,如果最后一天的任务是B,那么执行任务A,否则执行将不执行任务的天数最小化的任务。
  • 使用变量 last 来跟踪前一天的任务,它可以采用以下值:
    • 0 – 未执行任何任务。
    • 1 – 执行的 A 类任务
    • 2 – 执行的 B 类任务

下面是上述方法的实现。

C++
#include 
using namespace std;
 
int solve(int a[], int last, int n)
{
    // Base case
    if (n == 0)
        return 0;
 
    // Condition 1 (no task) so does nothing
    if (a[n - 1] == 0) {
        // Increase count
        return 1 + solve(a, 0, n - 1);
    }
 
    // Condition 2 (only task B)
    else if (a[n - 1] == 1) {
        // Last task is of type B
        // so can't perform it again
        if (last == 2)
 
            // Increase count
            return 1 + solve(a, 0, n - 1);
        else
 
            // Perform task B
            return solve(a, 2, n - 1);
    }
 
    // Condition 3 (only task A )
    else if (a[n - 1] == 2) {
        // Last task is of type A
        // so can't perform it again
        if (last == 1)
 
            // Increase count
            return 1 + solve(a, 0, n - 1);
        else
 
            // Perform task A
            return solve(a, 1, n - 1);
    }
 
    // Condition 4 (both task A and B)
    else {
        // Last task is of type A
        if (last == 1)
 
            // Perform task B
            return solve(a, 2, n - 1);
 
        // Last task is of type B
        else if (last == 2)
 
            // Perform task A
            return solve(a, 1, n - 1);
        else
 
            // Perform the minimum among both
            return min(solve(a, 2, n - 1),
                       solve(a, 1, n - 1));
    }
}
 
int main()
{
    // Number of days
    int N = 4;
    int arr[] = { 0, 1, 3, 2 };
 
    cout << solve(arr, 0, N) << endl;
 
    return 0;
}


Java
import java.util.*;
 
public class GFG
{
 
static int solve(int []a, int last, int n)
{
    // Base case
    if (n == 0)
        return 0;
 
    // Condition 1 (no task) so does nothing
    if (a[n - 1] == 0) {
        // Increase count
        return 1 + solve(a, 0, n - 1);
    }
 
    // Condition 2 (only task B)
    else if (a[n - 1] == 1) {
        // Last task is of type B
        // so can't perform it again
        if (last == 2)
 
            // Increase count
            return 1 + solve(a, 0, n - 1);
        else
 
            // Perform task B
            return solve(a, 2, n - 1);
    }
 
    // Condition 3 (only task A )
    else if (a[n - 1] == 2) {
        // Last task is of type A
        // so can't perform it again
        if (last == 1)
 
            // Increase count
            return 1 + solve(a, 0, n - 1);
        else
 
            // Perform task A
            return solve(a, 1, n - 1);
    }
 
    // Condition 4 (both task A and B)
    else {
        // Last task is of type A
        if (last == 1)
 
            // Perform task B
            return solve(a, 2, n - 1);
 
        // Last task is of type B
        else if (last == 2)
 
            // Perform task A
            return solve(a, 1, n - 1);
        else
 
            // Perform the minimum among both
            return Math.min(solve(a, 2, n - 1),
                       solve(a, 1, n - 1));
    }
}
 
public static void main(String args[])
{
    // Number of days
    int N = 4;
    int []arr = { 0, 1, 3, 2 };
 
    System.out.println(solve(arr, 0, N));
 
}
}
// This code is contributed by Samim Hossain Mondal.


Python3
def solve(a, last, n):
   
    # Base case
    if (n == 0):
        return 0
 
    # Condition 1 (no task) so does nothing
    if (a[n - 1] == 0):
       
        # Increase count
        return 1 + solve(a, 0, n - 1)
     
 
    # Condition 2 (only task B)
    elif (a[n - 1] == 1):
       
        # Last task is of type B
        # so can't perform it again
        if (last == 2):
           
            # Increase count
            return 1 + solve(a, 0, n - 1)
        else:
            # Perform task B
            return solve(a, 2, n - 1)
     
 
    # Condition 3 (only task A )
    elif (a[n - 1] == 2):
       
        # Last task is of type A
        # so can't perform it again
        if (last == 1):
           
            # Increase count
            return 1 + solve(a, 0, n - 1)
        else:
            # Perform task A
            return solve(a, 1, n - 1)
     
 
    # Condition 4 (both task A and B)
    else:
        # Last task is of type A
        if (last == 1):
 
            # Perform task B
            return solve(a, 2, n - 1)
 
        # Last task is of type B
        elif (last == 2):
 
            # Perform task A
            return solve(a, 1, n - 1)
        else:
 
            # Perform the minimum among both
            return min(solve(a, 2, n - 1),
                        solve(a, 1, n - 1))
     
# Number of days
N = 4
arr = [0, 1, 3, 2]
 
print(solve(arr, 0, N))
 
# This code is contributed by gfgking.


C#
using System;
 
class GFG
{
 
static int solve(int []a, int last, int n)
{
    // Base case
    if (n == 0)
        return 0;
 
    // Condition 1 (no task) so does nothing
    if (a[n - 1] == 0) {
        // Increase count
        return 1 + solve(a, 0, n - 1);
    }
 
    // Condition 2 (only task B)
    else if (a[n - 1] == 1) {
        // Last task is of type B
        // so can't perform it again
        if (last == 2)
 
            // Increase count
            return 1 + solve(a, 0, n - 1);
        else
 
            // Perform task B
            return solve(a, 2, n - 1);
    }
 
    // Condition 3 (only task A )
    else if (a[n - 1] == 2) {
        // Last task is of type A
        // so can't perform it again
        if (last == 1)
 
            // Increase count
            return 1 + solve(a, 0, n - 1);
        else
 
            // Perform task A
            return solve(a, 1, n - 1);
    }
 
    // Condition 4 (both task A and B)
    else {
        // Last task is of type A
        if (last == 1)
 
            // Perform task B
            return solve(a, 2, n - 1);
 
        // Last task is of type B
        else if (last == 2)
 
            // Perform task A
            return solve(a, 1, n - 1);
        else
 
            // Perform the minimum among both
            return Math.Min(solve(a, 2, n - 1),
                       solve(a, 1, n - 1));
    }
}
 
public static void Main()
{
    // Number of days
    int N = 4;
    int []arr = { 0, 1, 3, 2 };
 
    Console.Write(solve(arr, 0, N));
 
}
}
// This code is contributed by Samim Hossain Mondal.


Javascript


C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
int dp[101][3];
 
int solve(int a[], int last, int n)
{
    // Base case
    if (n == 0)
        return 0;
 
    // If the value is pre-calculated return it
    if (dp[n][last] != -1)
        return dp[n][last];
 
    // Condition 1 (no task) so does nothing
    if (a[n - 1] == 0) {
        // Increase count
        return dp[n][last] = 1
                             + solve(a, 0, n - 1);
    }
    // Condition 2 (only task B)
    else if (a[n - 1] == 1) {
        // Last task is of type B
        // so can't perform it again
        if (last == 2)
 
            // Increase count
            return dp[n][last] = 1
                                 + solve(a, 0, n - 1);
        else
            // Perform task B
            return dp[n][last]
                   = solve(a, 2, n - 1);
    }
 
    // Condition 3 (only task A )
    else if (a[n - 1] == 2) {
        // Last task is of type A so can't
 
        if (last == 1)
 
            // Increase count
            return dp[n][last] = 1
                                 + solve(a, 0, n - 1);
        else
 
            // Perform task A
            return dp[n][last]
                   = solve(a, 1, n - 1);
    }
    // Condition 4 (both task A and B)
    else {
        // Last task is of type A
        if (last == 1)
 
            // Perform task B
            return dp[n][last]
                   = solve(a, 2, n - 1);
 
        // Last task is of type B
        else if (last == 2)
            return dp[n][last]
                   = solve(a, 1, n - 1);
 
        // Perform task A
        else
 
            // Perform the minimum among both
            return dp[n][last]
                   = min(solve(a, 2, n - 1),
                         solve(a, 1, n - 1));
    }
}
 
int main()
{
    int N = 4;
    int arr[] = { 0, 1, 3, 2 };
 
    // Initialize the space with -1
    memset(dp, -1, sizeof(dp));
 
    cout << solve(arr, 0, N) << endl;
 
    return 0;
}


Java
// Java Program to implement
// the above approach
import java.util.*;
 
public class GFG
{
     
static int dp[][] = new int[101][3];
 
static int solve(int []a, int last, int n)
{
    // Base case
    if (n == 0)
        return 0;
 
    // If the value is pre-calculated return it
    if (dp[n][last] != -1)
        return dp[n][last];
 
    // Condition 1 (no task) so does nothing
    if (a[n - 1] == 0) {
        // Increase count
        return dp[n][last] = 1
                             + solve(a, 0, n - 1);
    }
    // Condition 2 (only task B)
    else if (a[n - 1] == 1) {
        // Last task is of type B
        // so can't perform it again
        if (last == 2)
 
            // Increase count
            return dp[n][last] = 1
                                 + solve(a, 0, n - 1);
        else
            // Perform task B
            return dp[n][last]
                   = solve(a, 2, n - 1);
    }
 
    // Condition 3 (only task A )
    else if (a[n - 1] == 2) {
        // Last task is of type A so can't
 
        if (last == 1)
 
            // Increase count
            return dp[n][last] = 1
                                 + solve(a, 0, n - 1);
        else
 
            // Perform task A
            return dp[n][last]
                   = solve(a, 1, n - 1);
    }
    // Condition 4 (both task A and B)
    else {
        // Last task is of type A
        if (last == 1)
 
            // Perform task B
            return dp[n][last]
                   = solve(a, 2, n - 1);
 
        // Last task is of type B
        else if (last == 2)
            return dp[n][last]
                   = solve(a, 1, n - 1);
 
        // Perform task A
        else
 
            // Perform the minimum among both
            return dp[n][last]
                   = Math.min(solve(a, 2, n - 1),
                         solve(a, 1, n - 1));
    }
}
 
public static void main(String args[])
{
    // Number of days
    int N = 4;
    int []arr = { 0, 1, 3, 2 };
     
    for(int i = 0; i < 101; i++) {
        for(int j = 0; j < 3; j++) {
            dp[i][j] = -1;
        }
    }
 
    System.out.println(solve(arr, 0, N));
 
}
}
// This code is contributed by Samim Hossain Mondal.


Python3
# Python3 program to implement
# the above approach
dp = [0] * 101
 
def solve(a, last, n):
     
    # Base case
    if (n == 0):
        return 0
 
    # If the value is pre-calculated return it
    if (dp[n][last] != -1):
        return dp[n][last]
 
    # Condition 1 (no task) so does nothing
    if (a[n - 1] == 0):
         
        # Increase count
        dp[n][last] = 1 + solve(a, 0, n - 1)
 
        return dp[n][last]
 
    # Condition 2 (only task B)
    elif (a[n - 1] == 1):
 
        # Last task is of type B
        # so can't perform it again
        if (last == 2):
             
            # Increase count
            dp[n][last] = 1 + solve(a, 0, n - 1)
            return dp[n][last]
        else:
             
            # Perform task B
            dp[n][last] = solve(a, 2, n - 1)
            return dp[n][last]
 
    # Condition 3 (only task A )
    elif (a[n - 1] == 2):
 
        # Last task is of type A so can't
        if (last == 1):
 
            # Increase count
            dp[n][last] = 1 + solve(a, 0, n - 1)
            return dp[n][last]
        else:
            dp[n][last] = solve(a, 1, n - 1)
             
            # Perform task A
            return dp[n][last]
 
    # Condition 4 (both task A and B)
    else:
 
        # Last task is of type A
        if (last == 1):
            dp[n][last] = solve(a, 2, n - 1)
             
            # Perform task B
            return dp[n][last]
 
        # Last task is of type B
        elif (last == 2):
            dp[n][last] = solve(a, 1, n - 1)
            return dp[n][last]
 
        # Perform task A
        else:
            dp[n][last] = min(solve(a, 2, n - 1),
                              solve(a, 1, n - 1))
             
            # Perform the minimum among both
            return dp[n][last]
 
# Driver code
N = 4
arr = [ 0, 1, 3, 2 ]
 
# Initialize the space with -1
for i in range(len(dp)):
    dp[i] = [-1] * 3
 
print(solve(arr, 0, N))
 
# This code is contributed by Saurabh Jaiswal


C#
// C# Program to implement
// the above approach
using System;
 
class GFG
{
     
static int [,]dp = new int[101, 3];
 
static int solve(int []a, int last, int n)
{
    // Base case
    if (n == 0)
        return 0;
 
    // If the value is pre-calculated return it
    if (dp[n, last] != -1)
        return dp[n, last];
 
    // Condition 1 (no task) so does nothing
    if (a[n - 1] == 0) {
        // Increase count
        return dp[n, last] = 1
                             + solve(a, 0, n - 1);
    }
    // Condition 2 (only task B)
    else if (a[n - 1] == 1) {
        // Last task is of type B
        // so can't perform it again
        if (last == 2)
 
            // Increase count
            return dp[n, last] = 1
                                 + solve(a, 0, n - 1);
        else
            // Perform task B
            return dp[n, last]
                   = solve(a, 2, n - 1);
    }
 
    // Condition 3 (only task A )
    else if (a[n - 1] == 2) {
        // Last task is of type A so can't
 
        if (last == 1)
 
            // Increase count
            return dp[n, last] = 1
                                 + solve(a, 0, n - 1);
        else
 
            // Perform task A
            return dp[n, last]
                   = solve(a, 1, n - 1);
    }
    // Condition 4 (both task A and B)
    else {
        // Last task is of type A
        if (last == 1)
 
            // Perform task B
            return dp[n, last]
                   = solve(a, 2, n - 1);
 
        // Last task is of type B
        else if (last == 2)
            return dp[n, last]
                   = solve(a, 1, n - 1);
 
        // Perform task A
        else
 
            // Perform the minimum among both
            return dp[n, last]
                   = Math.Min(solve(a, 2, n - 1),
                         solve(a, 1, n - 1));
    }
}
 
public static void Main()
{
    // Number of days
    int N = 4;
    int []arr = { 0, 1, 3, 2 };
     
    for(int i = 0; i < 101; i++) {
        for(int j = 0; j < 3; j++) {
            dp[i, j] = -1;
        }
    }
 
    Console.Write(solve(arr, 0, N));
 
}
}
// This code is contributed by Samim Hossain Mondal.


Javascript


输出
2

有效的方法:为了优化上述方法,可以使用动态规划。使用记忆来存储先前的状态,以便可以利用这些先前的状态来计算进一步的结果。

下面是上述方法的实现:

C++

// C++ Program to implement
// the above approach
#include 
using namespace std;
 
int dp[101][3];
 
int solve(int a[], int last, int n)
{
    // Base case
    if (n == 0)
        return 0;
 
    // If the value is pre-calculated return it
    if (dp[n][last] != -1)
        return dp[n][last];
 
    // Condition 1 (no task) so does nothing
    if (a[n - 1] == 0) {
        // Increase count
        return dp[n][last] = 1
                             + solve(a, 0, n - 1);
    }
    // Condition 2 (only task B)
    else if (a[n - 1] == 1) {
        // Last task is of type B
        // so can't perform it again
        if (last == 2)
 
            // Increase count
            return dp[n][last] = 1
                                 + solve(a, 0, n - 1);
        else
            // Perform task B
            return dp[n][last]
                   = solve(a, 2, n - 1);
    }
 
    // Condition 3 (only task A )
    else if (a[n - 1] == 2) {
        // Last task is of type A so can't
 
        if (last == 1)
 
            // Increase count
            return dp[n][last] = 1
                                 + solve(a, 0, n - 1);
        else
 
            // Perform task A
            return dp[n][last]
                   = solve(a, 1, n - 1);
    }
    // Condition 4 (both task A and B)
    else {
        // Last task is of type A
        if (last == 1)
 
            // Perform task B
            return dp[n][last]
                   = solve(a, 2, n - 1);
 
        // Last task is of type B
        else if (last == 2)
            return dp[n][last]
                   = solve(a, 1, n - 1);
 
        // Perform task A
        else
 
            // Perform the minimum among both
            return dp[n][last]
                   = min(solve(a, 2, n - 1),
                         solve(a, 1, n - 1));
    }
}
 
int main()
{
    int N = 4;
    int arr[] = { 0, 1, 3, 2 };
 
    // Initialize the space with -1
    memset(dp, -1, sizeof(dp));
 
    cout << solve(arr, 0, N) << endl;
 
    return 0;
}

Java

// Java Program to implement
// the above approach
import java.util.*;
 
public class GFG
{
     
static int dp[][] = new int[101][3];
 
static int solve(int []a, int last, int n)
{
    // Base case
    if (n == 0)
        return 0;
 
    // If the value is pre-calculated return it
    if (dp[n][last] != -1)
        return dp[n][last];
 
    // Condition 1 (no task) so does nothing
    if (a[n - 1] == 0) {
        // Increase count
        return dp[n][last] = 1
                             + solve(a, 0, n - 1);
    }
    // Condition 2 (only task B)
    else if (a[n - 1] == 1) {
        // Last task is of type B
        // so can't perform it again
        if (last == 2)
 
            // Increase count
            return dp[n][last] = 1
                                 + solve(a, 0, n - 1);
        else
            // Perform task B
            return dp[n][last]
                   = solve(a, 2, n - 1);
    }
 
    // Condition 3 (only task A )
    else if (a[n - 1] == 2) {
        // Last task is of type A so can't
 
        if (last == 1)
 
            // Increase count
            return dp[n][last] = 1
                                 + solve(a, 0, n - 1);
        else
 
            // Perform task A
            return dp[n][last]
                   = solve(a, 1, n - 1);
    }
    // Condition 4 (both task A and B)
    else {
        // Last task is of type A
        if (last == 1)
 
            // Perform task B
            return dp[n][last]
                   = solve(a, 2, n - 1);
 
        // Last task is of type B
        else if (last == 2)
            return dp[n][last]
                   = solve(a, 1, n - 1);
 
        // Perform task A
        else
 
            // Perform the minimum among both
            return dp[n][last]
                   = Math.min(solve(a, 2, n - 1),
                         solve(a, 1, n - 1));
    }
}
 
public static void main(String args[])
{
    // Number of days
    int N = 4;
    int []arr = { 0, 1, 3, 2 };
     
    for(int i = 0; i < 101; i++) {
        for(int j = 0; j < 3; j++) {
            dp[i][j] = -1;
        }
    }
 
    System.out.println(solve(arr, 0, N));
 
}
}
// This code is contributed by Samim Hossain Mondal.

Python3

# Python3 program to implement
# the above approach
dp = [0] * 101
 
def solve(a, last, n):
     
    # Base case
    if (n == 0):
        return 0
 
    # If the value is pre-calculated return it
    if (dp[n][last] != -1):
        return dp[n][last]
 
    # Condition 1 (no task) so does nothing
    if (a[n - 1] == 0):
         
        # Increase count
        dp[n][last] = 1 + solve(a, 0, n - 1)
 
        return dp[n][last]
 
    # Condition 2 (only task B)
    elif (a[n - 1] == 1):
 
        # Last task is of type B
        # so can't perform it again
        if (last == 2):
             
            # Increase count
            dp[n][last] = 1 + solve(a, 0, n - 1)
            return dp[n][last]
        else:
             
            # Perform task B
            dp[n][last] = solve(a, 2, n - 1)
            return dp[n][last]
 
    # Condition 3 (only task A )
    elif (a[n - 1] == 2):
 
        # Last task is of type A so can't
        if (last == 1):
 
            # Increase count
            dp[n][last] = 1 + solve(a, 0, n - 1)
            return dp[n][last]
        else:
            dp[n][last] = solve(a, 1, n - 1)
             
            # Perform task A
            return dp[n][last]
 
    # Condition 4 (both task A and B)
    else:
 
        # Last task is of type A
        if (last == 1):
            dp[n][last] = solve(a, 2, n - 1)
             
            # Perform task B
            return dp[n][last]
 
        # Last task is of type B
        elif (last == 2):
            dp[n][last] = solve(a, 1, n - 1)
            return dp[n][last]
 
        # Perform task A
        else:
            dp[n][last] = min(solve(a, 2, n - 1),
                              solve(a, 1, n - 1))
             
            # Perform the minimum among both
            return dp[n][last]
 
# Driver code
N = 4
arr = [ 0, 1, 3, 2 ]
 
# Initialize the space with -1
for i in range(len(dp)):
    dp[i] = [-1] * 3
 
print(solve(arr, 0, N))
 
# This code is contributed by Saurabh Jaiswal

C#

// C# Program to implement
// the above approach
using System;
 
class GFG
{
     
static int [,]dp = new int[101, 3];
 
static int solve(int []a, int last, int n)
{
    // Base case
    if (n == 0)
        return 0;
 
    // If the value is pre-calculated return it
    if (dp[n, last] != -1)
        return dp[n, last];
 
    // Condition 1 (no task) so does nothing
    if (a[n - 1] == 0) {
        // Increase count
        return dp[n, last] = 1
                             + solve(a, 0, n - 1);
    }
    // Condition 2 (only task B)
    else if (a[n - 1] == 1) {
        // Last task is of type B
        // so can't perform it again
        if (last == 2)
 
            // Increase count
            return dp[n, last] = 1
                                 + solve(a, 0, n - 1);
        else
            // Perform task B
            return dp[n, last]
                   = solve(a, 2, n - 1);
    }
 
    // Condition 3 (only task A )
    else if (a[n - 1] == 2) {
        // Last task is of type A so can't
 
        if (last == 1)
 
            // Increase count
            return dp[n, last] = 1
                                 + solve(a, 0, n - 1);
        else
 
            // Perform task A
            return dp[n, last]
                   = solve(a, 1, n - 1);
    }
    // Condition 4 (both task A and B)
    else {
        // Last task is of type A
        if (last == 1)
 
            // Perform task B
            return dp[n, last]
                   = solve(a, 2, n - 1);
 
        // Last task is of type B
        else if (last == 2)
            return dp[n, last]
                   = solve(a, 1, n - 1);
 
        // Perform task A
        else
 
            // Perform the minimum among both
            return dp[n, last]
                   = Math.Min(solve(a, 2, n - 1),
                         solve(a, 1, n - 1));
    }
}
 
public static void Main()
{
    // Number of days
    int N = 4;
    int []arr = { 0, 1, 3, 2 };
     
    for(int i = 0; i < 101; i++) {
        for(int j = 0; j < 3; j++) {
            dp[i, j] = -1;
        }
    }
 
    Console.Write(solve(arr, 0, N));
 
}
}
// This code is contributed by Samim Hossain Mondal.

Javascript


输出
2

时间复杂度: O(N),其中 N 是 arr[] 的大小。
辅助空间: O(N),其中 N 是 arr[] 的大小。