📌  相关文章
📜  满足给定条件的两个给定数组中相同索引子数组的最大长度

📅  最后修改于: 2021-04-24 23:51:31             🧑  作者: Mango

给定两个数组arr []brr []以及一个整数C ,任务是找到相同索引子数组的最大可能长度,例如K ,使得brr []中K长度子数组中最大元素的总和为Karr []K长度子数组之和之间的乘积不超过C。

例子:

天真的方法:最简单的方法是生成两个给定数组的所有可能的子数组,并考虑两个数组中所有相似的索引子数组,并检查给定条件。打印满足给定条件的子数组的最大长度。

时间复杂度: O(K * N 2 )
辅助空间: O(1)

基于二进制搜索的方法:为了优化上述方法,其思想是使用二进制搜索来找到K的可能值,并使用滑动窗口技术来找到长度为K的每个子数组的总和。请按照以下步骤解决问题:

  • 建立细分树以在所有可能范围内找到最大值。
  • [0,N]范围内执行二进制搜索以找到子数组的最大可能大小。
    • 初始化0N。
    • 找到中间2值作为(低+高)/。
    • 通过检查给定条件,检查是否有可能使子数组的最大大小为值。如果发现为真,则更新最大长度为(中间+ 1)。
    • 否则,更新(中- 1)。
  • 完成上述步骤后,打印存储的最大长度值。

下面是上述方法的实现:

C++14
// C++ program for the above approach
#include 
using namespace std;
 
// Stores the segment tree node values
int seg[10000];
 
// Function to find maximum element
// in the given range
int getMax(int b[], int ss, int se, int qs,
           int qe, int index)
{
     
    // If the query is out of bounds
    if (se < qs || ss > qe)
        return INT_MIN / 2;
 
    // If the segment is completey
    // inside the query range
    if (ss >= qs && se <= qe)
        return seg[index];
 
    // Calculte the mid
    int mid = ss + (se - ss) / 2;
 
    // Return maximum in left & right
    // of the segment tree recursively
    return max(
        getMax(b, ss, mid, qs,
               qe, 2 * index + 1),
        getMax(b, mid + 1, se,
               qs, qe, 2 * index + 2));
}
 
// Function to check if it is possible
// to have such a subarray of length K
bool possible(int a[], int b[], int n,
              int c, int k)
{
    int sum = 0;
     
    // Check for first window of size K
    for(int i = 0; i < k; i++)
    {
        sum += a[i];
    }
  
    // Calculte the total cost and
    // check if less than equal to c
    int total_cost = sum * k + getMax(
                     b, 0, n - 1,
                        0, k - 1, 0);
  
    // If it satisfy the condition
    if (total_cost <= c)
        return true;
  
    // Find the sum of current subarray
    // and calculate total cost
    for(int i = k; i < n; i++)
    {
         
        // Include the new element
        // of current subarray
        sum += a[i];
  
        // Discard the element
        // of last subarray
        sum -= a[i - k];
  
        // Calculate total cost
        // and check <=c
        total_cost = sum * k + getMax(
                     b, 0, n - 1,
                       i - k + 1, i, 0);
  
        // If possible, then
        // return true
        if (total_cost <= c)
            return true;
    }
  
    // If it is not possible
    return false;
}
 
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
int maxLength(int a[], int b[], int n, int c)
{
     
    // Base Case
    if (n == 0)
        return 0;
 
    // Let maximum length be 0
    int max_length = 0;
  
    int low = 0, high = n;
  
    // Perform Binary search
    while (low <= high)
    {
         
        // Find mid value
        int mid = low + (high - low) / 2;
         
        // Check if the current mid
        // satisfy the given condition
        if (possible(a, b, n, c, mid) != false)
        {
             
            // If yes, then store length
            max_length = mid;
            low = mid + 1;
        }
  
        // Otherwise
        else
            high = mid - 1;
    }
  
    // Return maximum length stored
    return max_length;
}
  
// Function that builds segment Tree
void build(int b[], int index, int s, int e)
{
     
    // If there is only one element
    if (s == e)
    {
        seg[index] = b[s];
        return;
    }
  
    // Find the value of mid
    int mid = s + (e - s) / 2;
 
    // Build left and right parts
    // of segement tree recursively
    build(b, 2 * index + 1, s, mid);
    build(b, 2 * index + 2, mid + 1, e);
 
    // Update the value at current
    // index
    seg[index] = max(
        seg[2 * index + 1],
        seg[2 * index + 2]);
}
 
// Function that initializes the
// segment Tree
void initialiseSegmentTree(int N)
{
    int seg[4 * N];
}
   
// Driver Code
int main()
{
    int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
    int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
      
    int C = 40;
      
    int N = sizeof(A) / sizeof(A[0]);
      
    // Initialize and Build the
    // Segment Tree
    initialiseSegmentTree(N);
    build(B, 0, 0, N - 1);
      
    // Function Call
    cout << (maxLength(A, B, N, C));
}
 
// This code is contributed by susmitakundugoaldanga


Java
// Java program for the above approach
 
import java.io.*;
import java.util.*;
class GFG {
 
    // Stores the segment tree node values
    static int seg[];
 
    // Function to find maximum length
    // of subarray such that sum of
    // maximum element in subarray in brr[] and
    // sum of subarray in arr[] * K is at most C
    public static int maxLength(
        int a[], int b[], int n, int c)
    {
        // Base Case
        if (n == 0)
            return 0;
 
        // Let maximum length be 0
        int max_length = 0;
 
        int low = 0, high = n;
 
        // Perform Binary search
        while (low <= high) {
 
            // Find mid value
            int mid = low + (high - low) / 2;
 
            // Check if the current mid
            // satisfy the given condition
            if (possible(a, b, n, c, mid)) {
 
                // If yes, then store length
                max_length = mid;
                low = mid + 1;
            }
 
            // Otherwise
            else
                high = mid - 1;
        }
 
        // Return maximum length stored
        return max_length;
    }
 
    // Function to check if it is possible
    // to have such a subarray of length K
    public static boolean possible(
        int a[], int b[], int n,
        int c, int k)
    {
        int sum = 0;
 
        // Check for first window of size K
        for (int i = 0; i < k; i++) {
            sum += a[i];
        }
 
        // Calculte the total cost and
        // check if less than equal to c
        int total_cost
            = sum * k + getMax(b, 0, n - 1,
                               0, k - 1, 0);
 
        // If it satisfy the condition
        if (total_cost <= c)
            return true;
 
        // Find the sum of current subarray
        // and calculate total cost
        for (int i = k; i < n; i++) {
 
            // Include the new element
            // of current subarray
            sum += a[i];
 
            // Discard the element
            // of last subarray
            sum -= a[i - k];
 
            // Calculate total cost
            // and check <=c
            total_cost
                = sum * k
                  + getMax(b, 0, n - 1,
                           i - k + 1, i, 0);
 
            // If possible, then
            // return true
            if (total_cost <= c)
                return true;
        }
 
        // If it is not possible
        return false;
    }
 
    // Function that builds segment Tree
    public static void build(
        int b[], int index, int s, int e)
    {
        // If there is only one element
        if (s == e) {
            seg[index] = b[s];
            return;
        }
 
        // Find the value of mid
        int mid = s + (e - s) / 2;
 
        // Build left and right parts
        // of segement tree recursively
        build(b, 2 * index + 1, s, mid);
        build(b, 2 * index + 2, mid + 1, e);
 
        // Update the value at current
        // index
        seg[index] = Math.max(
            seg[2 * index + 1],
            seg[2 * index + 2]);
    }
 
    // Function to find maximum element
    // in the given range
    public static int getMax(
        int b[], int ss, int se, int qs,
        int qe, int index)
    {
        // If the query is out of bounds
        if (se < qs || ss > qe)
            return Integer.MIN_VALUE / 2;
 
        // If the segment is completey
        // inside the query range
        if (ss >= qs && se <= qe)
            return seg[index];
 
        // Calculte the mid
        int mid = ss + (se - ss) / 2;
 
        // Return maximum in left & right
        // of the segment tree recursively
        return Math.max(
            getMax(b, ss, mid, qs,
                   qe, 2 * index + 1),
            getMax(b, mid + 1, se,
                   qs, qe, 2 * index + 2));
    }
 
    // Function that initializes the
    // segment Tree
    public static void
    initialiseSegmentTree(int N)
    {
        seg = new int[4 * N];
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
        int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
 
        int C = 40;
 
        int N = A.length;
 
        // Initialize and Build the
        // Segment Tree
        initialiseSegmentTree(N);
        build(B, 0, 0, N - 1);
 
        // Function Call
        System.out.println(maxLength(A, B, N, C));
    }
}


Python3
# Python3 program for the above approach
import math
 
# Stores the segment tree node values
seg = [0 for x in range(10000)]
INT_MIN = int(-10000000)
 
# Function to find maximum element
# in the given range
def getMax(b, ss, se, qs, qe, index):
     
    # If the query is out of bounds
    if (se < qs or ss > qe):
        return int(INT_MIN / 2)
         
    # If the segment is completey
    # inside the query range
    if (ss >= qs and se <= qe):
        return seg[index]
         
    # Calculte the mid
    mid = int(int(ss) + int((se - ss) / 2))
     
    # Return maximum in left & right
    # of the segment tree recursively
    return max(getMax(b, ss, mid, qs,
                      qe, 2 * index + 1),
               getMax(b, mid + 1, se, qs,
                      qe, 2 * index + 2))
 
# Function to check if it is possible
# to have such a subarray of length K
def possible(a,  b, n, c, k):
     
    sum = int(0)
     
    # Check for first window of size K
    for i in range(0, k):
        sum += a[i]
         
    # Calculte the total cost and
    # check if less than equal to c
    total_cost = int(sum * k +
              getMax(b, 0, n - 1,
                        0, k - 1, 0))
  
    # If it satisfy the condition
    if (total_cost <= c):
        return 1
 
    # Find the sum of current subarray
    # and calculate total cost
    for i in range (k, n):
         
        # Include the new element
        # of current subarray
        sum += a[i]
         
        # Discard the element
        # of last subarray
        sum -= a[i - k]
 
        # Calculate total cost
        # and check <=c
        total_cost = int(sum * k + getMax(
               b, 0, n - 1,i - k + 1, i, 0))
  
        # If possible, then
        # return true
        if (total_cost <= c):
            return 1
             
    # If it is not possible
    return 0
 
# Function to find maximum length
# of subarray such that sum of
# maximum element in subarray in brr[] and
# sum of subarray in arr[] * K is at most C
def maxLength(a, b, n, c):
     
    # Base Case
    if (n == 0):
        return 0
 
    # Let maximum length be 0
    max_length = int(0)
  
    low = 0
    high = n
     
    # Perform Binary search
    while (low <= high):
         
        # Find mid value
        mid = int(low + int((high - low) / 2))
         
        # Check if the current mid
        # satisfy the given condition
        if (possible(a, b, n, c, mid) != 0):
             
            # If yes, then store length
            max_length = mid
            low = mid + 1
             
        # Otherwise
        else:
            high = mid - 1
  
    # Return maximum length stored
    return max_length
  
# Function that builds segment Tree
def build(b, index, s, e):
     
    # If there is only one element
    if (s == e):
        seg[index] = b[s]
        return
     
    # Find the value of mid
    mid = int(s + int((e - s) / 2))
 
    # Build left and right parts
    # of segement tree recursively
    build(b, 2 * index + 1, s, mid)
    build(b, 2 * index + 2, mid + 1, e)
 
    # Update the value at current
    # index
    seg[index] = max(seg[2 * index + 1],
                     seg[2 * index + 2])
 
#  Driver Code
A = [ 1, 2, 1, 6, 5, 5, 6, 1 ]
B = [ 14, 8, 15, 15, 9, 10, 7, 12 ]    
 
C = int(40)
N = len(A) 
 
# Initialize and Build the
# Segment Tree
build(B, 0, 0, N - 1)
 
# Function Call
print((maxLength(A, B, N, C)))
 
# This code is contributed by Stream_Cipher


C#
// C# program for the above approach
using System;
 
class GFG{
     
// Stores the segment tree node values
static int[] seg;
 
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
static int maxLength(int[] a, int[] b,
                     int n, int c)
{
     
    // Base Case
    if (n == 0)
        return 0;
 
    // Let maximum length be 0
    int max_length = 0;
 
    int low = 0, high = n;
 
    // Perform Binary search
    while (low <= high)
    {
         
        // Find mid value
        int mid = low + (high - low) / 2;
 
        // Check if the current mid
        // satisfy the given condition
        if (possible(a, b, n, c, mid))
        {
             
            // If yes, then store length
            max_length = mid;
            low = mid + 1;
        }
 
        // Otherwise
        else
            high = mid - 1;
    }
 
    // Return maximum length stored
    return max_length;
}
 
// Function to check if it is possible
// to have such a subarray of length K
static bool possible(int[] a, int[] b, int n,
                     int c, int k)
{
    int sum = 0;
 
    // Check for first window of size K
    for(int i = 0; i < k; i++)
    {
        sum += a[i];
    }
 
    // Calculte the total cost and
    // check if less than equal to c
    int total_cost = sum * k +
              getMax(b, 0, n - 1,
                        0, k - 1, 0);
 
    // If it satisfy the condition
    if (total_cost <= c)
        return true;
 
    // Find the sum of current subarray
    // and calculate total cost
    for(int i = k; i < n; i++)
    {
         
        // Include the new element
        // of current subarray
        sum += a[i];
 
        // Discard the element
        // of last subarray
        sum -= a[i - k];
 
        // Calculate total cost
        // and check <=c
        total_cost = sum * k +
              getMax(b, 0, n - 1,
                       i - k + 1, i, 0);
 
        // If possible, then
        // return true
        if (total_cost <= c)
            return true;
    }
 
    // If it is not possible
    return false;
}
 
// Function that builds segment Tree
static void build(int[] b, int index,
                  int s, int e)
{
     
    // If there is only one element
    if (s == e)
    {
        seg[index] = b[s];
        return;
    }
 
    // Find the value of mid
    int mid = s + (e - s) / 2;
 
    // Build left and right parts
    // of segement tree recursively
    build(b, 2 * index + 1, s, mid);
    build(b, 2 * index + 2, mid + 1, e);
 
    // Update the value at current
    // index
    seg[index] = Math.Max(
        seg[2 * index + 1],
        seg[2 * index + 2]);
}
 
// Function to find maximum element
// in the given range
public static int getMax(int[] b, int ss,
                         int se, int qs,
                         int qe, int index)
{
     
    // If the query is out of bounds
    if (se < qs || ss > qe)
        return Int32.MinValue / 2;
 
    // If the segment is completey
    // inside the query range
    if (ss >= qs && se <= qe)
        return seg[index];
 
    // Calculte the mid
    int mid = ss + (se - ss) / 2;
 
    // Return maximum in left & right
    // of the segment tree recursively
    return Math.Max(
        getMax(b, ss, mid, qs,
               qe, 2 * index + 1),
        getMax(b, mid + 1, se,
               qs, qe, 2 * index + 2));
}
 
// Function that initializes the
// segment Tree
static void initialiseSegmentTree(int N)
{
    seg = new int[4 * N];
}
 
// Driver Code   
static void Main()
{
    int[] A = { 1, 2, 1, 6, 5, 5, 6, 1 };
    int[] B = { 14, 8, 15, 15, 9, 10, 7, 12 };
 
    int C = 40;
 
    int N = A.Length;
 
    // Initialize and Build the
    // Segment Tree
    initialiseSegmentTree(N);
    build(B, 0, 0, N - 1);
 
    // Function Call
    Console.WriteLine(maxLength(A, B, N, C));
}
}
 
// This code is contributed by divyesh072019


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to check if it is possible
// to have such a subarray of length K
bool possible(int a[], int b[], int n, int c,
                        int k)
{
 
    // Finds the maximum element
    // in each window of size k
    deque  dq;
 
    // Check for window of size K
    int sum = 0;
 
    // For all possible subarrays of
    // length k
    for (int i = 0; i < k; i++)
    {
        sum += a[i];
 
        // Until deque is empty
        while (dq.size() > 0 && b[i] > b[dq.back()])
            dq.pop_back();
        dq.push_back(i);
    }
 
    // Calculte the total cost and
    // check if less than equal to c
    int total_cost = sum * k + b[dq.front()];
    if (total_cost <= c)
        return true;
 
    // Find sum of current subarray
    // and the total cost
    for (int i = k; i < n; i++)
    {
 
        // Include the new element
        // of current subarray
        sum += a[i];
 
        // Discard the element
        // of last subarray
        sum -= a[i - k];
 
        // Remove all the elements
        // in the old window
        while (dq.size() > 0 && dq.front() <= i - k)
            dq.pop_front();
        while (dq.size() > 0 && b[i] > b[dq.back()])
            dq.pop_back();     
        dq.push_back(i);
 
        // Calculate total cost
        // and check <=c
        total_cost = sum * k + b[dq.front()];
 
        // If current subarray
        // length satisfies
        if (total_cost <= c)
            return true;
    }
 
    // If it is not possible
    return false;
}
 
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
int maxLength(int a[], int b[], int n, int c)
{
   
    // Base Case
    if (n == 0)
        return 0;
 
    // Let maximum length be 0
    int max_length = 0;
    int low = 0, high = n;
 
    // Perform Binary search
    while (low <= high)
    {
 
        // Find mid value
        int mid = low + (high - low) / 2;
 
        // Check if the current mid
        // satisfy the given condition
        if (possible(a, b, n, c, mid))
        {
 
            // If yes, then store length
            max_length = mid;
            low = mid + 1;
        }
 
        // Otherwise
        else
            high = mid - 1;
    }
 
    // Return maximum length stored
    return max_length;
}
 
// Driver Code
int main()
{
 
    int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
    int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
    int N = sizeof(A)/sizeof(A[0]);
    int C = 40;
    cout << maxLength(A, B, N, C);
    return 0;
}
 
// This code is contributed by Dharanendra L V


Java
// Java program for the above approach
 
import java.io.*;
import java.util.*;
class GFG {
 
    // Function to find maximum length
    // of subarray such that sum of
    // maximum element in subarray in brr[] and
    // sum of subarray in arr[] * K is at most C
    public static int maxLength(
        int a[], int b[], int n, int c)
    {
        // Base Case
        if (n == 0)
            return 0;
 
        // Let maximum length be 0
        int max_length = 0;
 
        int low = 0, high = n;
 
        // Perform Binary search
        while (low <= high) {
 
            // Find mid value
            int mid = low + (high - low) / 2;
 
            // Check if the current mid
            // satisfy the given condition
            if (possible(a, b, n, c, mid)) {
 
                // If yes, then store length
                max_length = mid;
                low = mid + 1;
            }
 
            // Otherwise
            else
                high = mid - 1;
        }
 
        // Return maximum length stored
        return max_length;
    }
 
    // Function to check if it is possible
    // to have such a subarray of length K
    public static boolean possible(
        int a[], int b[], int n, int c, int k)
    {
 
        // Finds the maximum element
        // in each window of size k
        Deque dq
            = new LinkedList();
 
        // Check for window of size K
        int sum = 0;
 
        // For all possible subarrays of
        // length k
        for (int i = 0; i < k; i++) {
 
            sum += a[i];
 
            // Until deque is empty
            while (dq.size() > 0
                   && b[i] > b[dq.peekLast()])
                dq.pollLast();
            dq.addLast(i);
        }
 
        // Calculte the total cost and
        // check if less than equal to c
        int total_cost = sum * k
                         + b[dq.peekFirst()];
        if (total_cost <= c)
            return true;
 
        // Find sum of current subarray
        // and the total cost
        for (int i = k; i < n; i++) {
 
            // Include the new element
            // of current subarray
            sum += a[i];
 
            // Discard the element
            // of last subarray
            sum -= a[i - k];
 
            // Remove all the elements
            // in the old window
            while (dq.size() > 0
                   && dq.peekFirst()
                          <= i - k)
                dq.pollFirst();
 
            while (dq.size() > 0
                   && b[i]
                          > b[dq.peekLast()])
                dq.pollLast();
 
            dq.add(i);
 
            // Calculate total cost
            // and check <=c
            total_cost = sum * k
                         + b[dq.peekFirst()];
 
            // If current subarray
            // length satisfies
            if (total_cost <= c)
                return true;
        }
 
        // If it is not possible
        return false;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
        int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
 
        int N = A.length;
 
        int C = 40;
 
        System.out.println(
            maxLength(A, B, N, C));
    }
}


Python3
# Python3 program for the above approach
 
# Function to find maximum length
# of subarray such that sum of
# maximum element in subarray in brr[] and
# sum of subarray in []arr * K is at most C
def maxLength(a, b, n, c):
 
    # Base Case
    if(n == 0):
        return 0
 
    # Let maximum length be 0
    max_length = 0
    low = 0
    high = n
 
    # Perform Binary search
    while(low <= high):
 
        # Find mid value
        mid = int(low + (high - low) / 2)
 
        # Check if the current mid
        # satisfy the given condition
        if(possible(a, b, n, c, mid)):
 
            # If yes, then store length
            max_length = mid
            low = mid + 1
 
        # Otherwise
        else:
            high = mid - 1
 
    # Return maximum length stored
    return max_length
 
# Function to check if it is possible
# to have such a subarray of length K
def possible(a, b, n, c, k):
 
    # Finds the maximum element
    # in each window of size k
    dq = []
     
    # Check for window of size K
    Sum = 0
 
    # For all possible subarrays of
    # length k
    for i in range(k):
        Sum += a[i]
 
        # Until deque is empty
        while(len(dq) > 0 and b[i] > b[dq[len(dq) - 1]]):
            dq.pop(len(dq) - 1)
        dq.append(i)
 
    # Calculte the total cost and
    # check if less than equal to c
    total_cost = Sum * k + b[dq[0]]
    if(total_cost <= c):
        return True
 
    # Find sum of current subarray
    # and the total cost
    for i in range(k, n):
 
        # Include the new element
        # of current subarray
        Sum += a[i]
 
        # Discard the element
        # of last subarray
        Sum -= a[i - k]
 
        # Remove all the elements
        # in the old window
        while(len(dq) > 0 and dq[0] <= i - k):
            dq.pop(0)
        while(len(dq) > 0 and b[i] > b[dq[len(dq) - 1]]):
            dq.pop(len(dq) - 1)
        dq.append(i)
 
        # Calculate total cost
        # and check <=c
        total_cost = Sum * k + b[dq[0]]
 
        # If current subarray
        # length satisfies
        if(total_cost <= c):
            return True
     
    # If it is not possible
    return False
 
# Driver Code
A = [1, 2, 1, 6, 5, 5, 6, 1]
B = [14, 8, 15, 15, 9, 10, 7, 12]
N = len(A)
C = 40
print(maxLength(A, B, N, C))
 
# This code is contributed by avanitrachhadiya2155


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // Function to find maximum length
    // of subarray such that sum of
    // maximum element in subarray in brr[] and
    // sum of subarray in []arr * K is at most C
    public static int maxLength(
        int []a, int []b, int n, int c)
    {
        // Base Case
        if (n == 0)
            return 0;
 
        // Let maximum length be 0
        int max_length = 0;
 
        int low = 0, high = n;
 
        // Perform Binary search
        while (low <= high) {
 
            // Find mid value
            int mid = low + (high - low) / 2;
 
            // Check if the current mid
            // satisfy the given condition
            if (possible(a, b, n, c, mid)) {
 
                // If yes, then store length
                max_length = mid;
                low = mid + 1;
            }
 
            // Otherwise
            else
                high = mid - 1;
        }
 
        // Return maximum length stored
        return max_length;
    }
 
    // Function to check if it is possible
    // to have such a subarray of length K
    public static bool possible(
        int []a, int []b, int n, int c, int k)
    {
 
        // Finds the maximum element
        // in each window of size k
        List dq
            = new List();
 
        // Check for window of size K
        int sum = 0;
 
        // For all possible subarrays of
        // length k
        for (int i = 0; i < k; i++) {
 
            sum += a[i];
 
            // Until deque is empty
            while (dq.Count > 0
                   && b[i] > b[dq[dq.Count - 1]])
                dq.RemoveAt(dq.Count - 1);
            dq.Add(i);
        }
 
        // Calculte the total cost and
        // check if less than equal to c
        int total_cost = sum * k
                         + b[dq[0]];
        if (total_cost <= c)
            return true;
 
        // Find sum of current subarray
        // and the total cost
        for (int i = k; i < n; i++) {
 
            // Include the new element
            // of current subarray
            sum += a[i];
 
            // Discard the element
            // of last subarray
            sum -= a[i - k];
 
            // Remove all the elements
            // in the old window
            while (dq.Count > 0
                   && dq[0]
                          <= i - k)
                dq.RemoveAt(0);
 
            while (dq.Count > 0
                   && b[i]
                          > b[dq[dq.Count - 1]])
                dq.RemoveAt(dq.Count - 1);
 
            dq.Add(i);
 
            // Calculate total cost
            // and check <=c
            total_cost = sum * k
                         + b[dq[0]];
 
            // If current subarray
            // length satisfies
            if (total_cost <= c)
                return true;
        }
 
        // If it is not possible
        return false;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int []A = { 1, 2, 1, 6, 5, 5, 6, 1 };
        int []B = { 14, 8, 15, 15, 9, 10, 7, 12 };
 
        int N = A.Length;
 
        int C = 40;
 
        Console.WriteLine(
            maxLength(A, B, N, C));
    }
}
 
// This code is contributed by Amit Katiyar


输出:
3

时间复杂度: O(N *(log N) 2 )
辅助空间: O(N)

高效方法:为了优化上述方法,其思想是通过使用单调队列来使用Deque,以便对于固定长度的每个子数组,我们可以在O(1)时间中找到最大值。对于[i,i + K – 1]范围内的任何子数组,要计算的值表达式由下式给出:

步骤如下:

  • [0,N]范围内执行二进制搜索以找到子数组的最大可能大小。
    • 初始化0N。
    • 找到中间2值作为(低+高)/。
    • 检查是否可以使子数组的最大大小为中值或不为:
      • 使用双端队列在数组brr []中的每个大小为K的子数组中找到最大元素。
      • 查找表达式的值,如果最多为C,则打破此条件。
      • 否则,检查所有可能的子数组大小的中间值,以及表达式的值以及是否最大为C,然后打破此条件。
      • 如果以上条件均不满足,则返回false。
    • 如果当前位数满足给定条件,则将最大长度更新为中位数,将最低长度更新为(mid +1)
    • 否则,更新(中- 1)。
  • 完成上述步骤后,打印存储的最大长度值。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Function to check if it is possible
// to have such a subarray of length K
bool possible(int a[], int b[], int n, int c,
                        int k)
{
 
    // Finds the maximum element
    // in each window of size k
    deque  dq;
 
    // Check for window of size K
    int sum = 0;
 
    // For all possible subarrays of
    // length k
    for (int i = 0; i < k; i++)
    {
        sum += a[i];
 
        // Until deque is empty
        while (dq.size() > 0 && b[i] > b[dq.back()])
            dq.pop_back();
        dq.push_back(i);
    }
 
    // Calculte the total cost and
    // check if less than equal to c
    int total_cost = sum * k + b[dq.front()];
    if (total_cost <= c)
        return true;
 
    // Find sum of current subarray
    // and the total cost
    for (int i = k; i < n; i++)
    {
 
        // Include the new element
        // of current subarray
        sum += a[i];
 
        // Discard the element
        // of last subarray
        sum -= a[i - k];
 
        // Remove all the elements
        // in the old window
        while (dq.size() > 0 && dq.front() <= i - k)
            dq.pop_front();
        while (dq.size() > 0 && b[i] > b[dq.back()])
            dq.pop_back();     
        dq.push_back(i);
 
        // Calculate total cost
        // and check <=c
        total_cost = sum * k + b[dq.front()];
 
        // If current subarray
        // length satisfies
        if (total_cost <= c)
            return true;
    }
 
    // If it is not possible
    return false;
}
 
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
int maxLength(int a[], int b[], int n, int c)
{
   
    // Base Case
    if (n == 0)
        return 0;
 
    // Let maximum length be 0
    int max_length = 0;
    int low = 0, high = n;
 
    // Perform Binary search
    while (low <= high)
    {
 
        // Find mid value
        int mid = low + (high - low) / 2;
 
        // Check if the current mid
        // satisfy the given condition
        if (possible(a, b, n, c, mid))
        {
 
            // If yes, then store length
            max_length = mid;
            low = mid + 1;
        }
 
        // Otherwise
        else
            high = mid - 1;
    }
 
    // Return maximum length stored
    return max_length;
}
 
// Driver Code
int main()
{
 
    int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
    int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
    int N = sizeof(A)/sizeof(A[0]);
    int C = 40;
    cout << maxLength(A, B, N, C);
    return 0;
}
 
// This code is contributed by Dharanendra L V

Java

// Java program for the above approach
 
import java.io.*;
import java.util.*;
class GFG {
 
    // Function to find maximum length
    // of subarray such that sum of
    // maximum element in subarray in brr[] and
    // sum of subarray in arr[] * K is at most C
    public static int maxLength(
        int a[], int b[], int n, int c)
    {
        // Base Case
        if (n == 0)
            return 0;
 
        // Let maximum length be 0
        int max_length = 0;
 
        int low = 0, high = n;
 
        // Perform Binary search
        while (low <= high) {
 
            // Find mid value
            int mid = low + (high - low) / 2;
 
            // Check if the current mid
            // satisfy the given condition
            if (possible(a, b, n, c, mid)) {
 
                // If yes, then store length
                max_length = mid;
                low = mid + 1;
            }
 
            // Otherwise
            else
                high = mid - 1;
        }
 
        // Return maximum length stored
        return max_length;
    }
 
    // Function to check if it is possible
    // to have such a subarray of length K
    public static boolean possible(
        int a[], int b[], int n, int c, int k)
    {
 
        // Finds the maximum element
        // in each window of size k
        Deque dq
            = new LinkedList();
 
        // Check for window of size K
        int sum = 0;
 
        // For all possible subarrays of
        // length k
        for (int i = 0; i < k; i++) {
 
            sum += a[i];
 
            // Until deque is empty
            while (dq.size() > 0
                   && b[i] > b[dq.peekLast()])
                dq.pollLast();
            dq.addLast(i);
        }
 
        // Calculte the total cost and
        // check if less than equal to c
        int total_cost = sum * k
                         + b[dq.peekFirst()];
        if (total_cost <= c)
            return true;
 
        // Find sum of current subarray
        // and the total cost
        for (int i = k; i < n; i++) {
 
            // Include the new element
            // of current subarray
            sum += a[i];
 
            // Discard the element
            // of last subarray
            sum -= a[i - k];
 
            // Remove all the elements
            // in the old window
            while (dq.size() > 0
                   && dq.peekFirst()
                          <= i - k)
                dq.pollFirst();
 
            while (dq.size() > 0
                   && b[i]
                          > b[dq.peekLast()])
                dq.pollLast();
 
            dq.add(i);
 
            // Calculate total cost
            // and check <=c
            total_cost = sum * k
                         + b[dq.peekFirst()];
 
            // If current subarray
            // length satisfies
            if (total_cost <= c)
                return true;
        }
 
        // If it is not possible
        return false;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
        int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
 
        int N = A.length;
 
        int C = 40;
 
        System.out.println(
            maxLength(A, B, N, C));
    }
}

Python3

# Python3 program for the above approach
 
# Function to find maximum length
# of subarray such that sum of
# maximum element in subarray in brr[] and
# sum of subarray in []arr * K is at most C
def maxLength(a, b, n, c):
 
    # Base Case
    if(n == 0):
        return 0
 
    # Let maximum length be 0
    max_length = 0
    low = 0
    high = n
 
    # Perform Binary search
    while(low <= high):
 
        # Find mid value
        mid = int(low + (high - low) / 2)
 
        # Check if the current mid
        # satisfy the given condition
        if(possible(a, b, n, c, mid)):
 
            # If yes, then store length
            max_length = mid
            low = mid + 1
 
        # Otherwise
        else:
            high = mid - 1
 
    # Return maximum length stored
    return max_length
 
# Function to check if it is possible
# to have such a subarray of length K
def possible(a, b, n, c, k):
 
    # Finds the maximum element
    # in each window of size k
    dq = []
     
    # Check for window of size K
    Sum = 0
 
    # For all possible subarrays of
    # length k
    for i in range(k):
        Sum += a[i]
 
        # Until deque is empty
        while(len(dq) > 0 and b[i] > b[dq[len(dq) - 1]]):
            dq.pop(len(dq) - 1)
        dq.append(i)
 
    # Calculte the total cost and
    # check if less than equal to c
    total_cost = Sum * k + b[dq[0]]
    if(total_cost <= c):
        return True
 
    # Find sum of current subarray
    # and the total cost
    for i in range(k, n):
 
        # Include the new element
        # of current subarray
        Sum += a[i]
 
        # Discard the element
        # of last subarray
        Sum -= a[i - k]
 
        # Remove all the elements
        # in the old window
        while(len(dq) > 0 and dq[0] <= i - k):
            dq.pop(0)
        while(len(dq) > 0 and b[i] > b[dq[len(dq) - 1]]):
            dq.pop(len(dq) - 1)
        dq.append(i)
 
        # Calculate total cost
        # and check <=c
        total_cost = Sum * k + b[dq[0]]
 
        # If current subarray
        # length satisfies
        if(total_cost <= c):
            return True
     
    # If it is not possible
    return False
 
# Driver Code
A = [1, 2, 1, 6, 5, 5, 6, 1]
B = [14, 8, 15, 15, 9, 10, 7, 12]
N = len(A)
C = 40
print(maxLength(A, B, N, C))
 
# This code is contributed by avanitrachhadiya2155

C#

// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // Function to find maximum length
    // of subarray such that sum of
    // maximum element in subarray in brr[] and
    // sum of subarray in []arr * K is at most C
    public static int maxLength(
        int []a, int []b, int n, int c)
    {
        // Base Case
        if (n == 0)
            return 0;
 
        // Let maximum length be 0
        int max_length = 0;
 
        int low = 0, high = n;
 
        // Perform Binary search
        while (low <= high) {
 
            // Find mid value
            int mid = low + (high - low) / 2;
 
            // Check if the current mid
            // satisfy the given condition
            if (possible(a, b, n, c, mid)) {
 
                // If yes, then store length
                max_length = mid;
                low = mid + 1;
            }
 
            // Otherwise
            else
                high = mid - 1;
        }
 
        // Return maximum length stored
        return max_length;
    }
 
    // Function to check if it is possible
    // to have such a subarray of length K
    public static bool possible(
        int []a, int []b, int n, int c, int k)
    {
 
        // Finds the maximum element
        // in each window of size k
        List dq
            = new List();
 
        // Check for window of size K
        int sum = 0;
 
        // For all possible subarrays of
        // length k
        for (int i = 0; i < k; i++) {
 
            sum += a[i];
 
            // Until deque is empty
            while (dq.Count > 0
                   && b[i] > b[dq[dq.Count - 1]])
                dq.RemoveAt(dq.Count - 1);
            dq.Add(i);
        }
 
        // Calculte the total cost and
        // check if less than equal to c
        int total_cost = sum * k
                         + b[dq[0]];
        if (total_cost <= c)
            return true;
 
        // Find sum of current subarray
        // and the total cost
        for (int i = k; i < n; i++) {
 
            // Include the new element
            // of current subarray
            sum += a[i];
 
            // Discard the element
            // of last subarray
            sum -= a[i - k];
 
            // Remove all the elements
            // in the old window
            while (dq.Count > 0
                   && dq[0]
                          <= i - k)
                dq.RemoveAt(0);
 
            while (dq.Count > 0
                   && b[i]
                          > b[dq[dq.Count - 1]])
                dq.RemoveAt(dq.Count - 1);
 
            dq.Add(i);
 
            // Calculate total cost
            // and check <=c
            total_cost = sum * k
                         + b[dq[0]];
 
            // If current subarray
            // length satisfies
            if (total_cost <= c)
                return true;
        }
 
        // If it is not possible
        return false;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int []A = { 1, 2, 1, 6, 5, 5, 6, 1 };
        int []B = { 14, 8, 15, 15, 9, 10, 7, 12 };
 
        int N = A.Length;
 
        int C = 40;
 
        Console.WriteLine(
            maxLength(A, B, N, C));
    }
}
 
// This code is contributed by Amit Katiyar
输出:
3

时间复杂度: O(N * log N)
辅助空间: O(N)