📌  相关文章
📜  在数组上执行给定操作后,S模M的值的最大计数位于[L,R]范围内

📅  最后修改于: 2021-04-29 14:57:52             🧑  作者: Mango

给定N个整数的数组arr []以及整数M,L,R 。考虑变量S (最初为0 )。对给定数组中的每个元素执行以下操作后,任务是找到位于[L,R]范围内的S%M值的最大数量:

  • S中添加arr [i]arr [i] – 1
  • 将S更改为S%M

例子:

天真的方法:最简单的方法是遍历给定的数组arr []并将arr [i]arr [i – 1]添加到给定的S中,并检查S%M是否在[L,R]范围内。由于有两种可能性来选择给定的数字。因此,使用递归来递归地获取S%M的最大值在[L,R]范围内。

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

高效的方法:为了优化上述方法,其思想是使用动态编程存储重叠的子问题,然后找到S%M的最大数量在[L,R]范围内。请按照以下步骤解决问题:

  1. 初始化unordered_map dp以存储具有重叠子问题的状态的值。
  2. 将总和初始化为0 ,然后将arr [i]或arr [i] – 1值递归加到总和S上
  3. 在每个步骤中,检查S%M是否在[L,R]范围内。如果它在该范围内,则计算该值并在上面的映射dp中将此当前状态更新为1。否则将其更新为0
  4. 查找所有可能的组合后,返回位于[L,R]范围内的S%M的值的计数。

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Lookup table
map, int> dp;
  
// Function to count the value of S
// after adding arr[i] or arr[i - 1]
// to the sum S at each time
int countMagicNumbers(int idx, int sum,
                      int a[], int n,
                      int m, int l, int r)
{
    // Base Case
    if (idx == n) {
  
        // Store the mod value
        int temp = sum % m;
  
        // If the mod value lies in
        // the range then return 1
        if (temp == l || temp == r
            || (temp > l && temp < r))
            return dp[{ idx, sum }] = 1;
  
        // Else return 0
        else
            return dp[{ idx, sum }] = 0;
    }
  
    // Store the current state
    pair curr
        = make_pair(idx, sum);
  
    // If already computed, return the
    // computed value
    if (dp.find(curr) != dp.end())
        return dp[curr];
  
    // Recursively adding the elements
    // to the sum adding ai value
    int ls = countMagicNumbers(idx + 1,
                               sum + a[idx],
                               a, n,
                               m, l, r);
  
    // Adding arr[i] - 1 value
    int rs = countMagicNumbers(idx + 1,
                               sum + (a[idx] - 1),
                               a, n, m, l, r);
  
    // Return the maximum count to
    // check for root value as well
    int temp1 = max(ls, rs);
    int temp = sum % m;
  
    // Avoid counting idx = 0 as possible
    // solution we are using idx != 0
    if ((temp == l || temp == r
         || (temp > l && temp < r))
        && idx != 0) {
        temp1 += 1;
    }
  
    // Return the value of current state
    return dp[{ idx, sum }] = temp1;
}
  
// Driver Code
int main()
{
    int N = 5, M = 22, L = 14, R = 16;
    int arr[] = { 17, 11, 10, 8, 15 };
  
    cout << countMagicNumbers(0, 0, arr,
                              N, M, L, R);
  
    return 0;
}


Python3
# Python3 program for the above approach
  
# Lookup table
dp = {}
  
# Function to count the value of S
# after adding arr[i] or arr[i - 1]
# to the sum S at each time
def countMagicNumbers(idx, sum, a, n, m, l, r):
      
    # Base Case
    if (idx == n):
  
        # Store the mod value
        temp = sum % m
  
        # If the mod value lies in
        # the range then return 1
        if (temp == l or temp == r or 
           (temp > l and temp < r)):
            dp[(idx, sum)] = 1
            return dp[(idx, sum)]
  
        # Else return 0
        else:
            dp[(idx, sum)] = 0
            return dp[(idx, sum)]
  
    # Store the current state
    curr = (idx, sum)
  
    # If already computed, return the
    # computed value
    if (curr in dp):
        return dp[curr]
  
    # Recursively adding the elements
    # to the sum adding ai value
    ls = countMagicNumbers(idx + 1,
                           sum + a[idx],
                           a, n, m, l, r)
  
    # Adding arr[i] - 1 value
    rs = countMagicNumbers(idx + 1,
                           sum + (a[idx] - 1),
                           a, n, m, l, r)
  
    # Return the maximum count to
    # check for root value as well
    temp1 = max(ls, rs)
    temp = sum % m
  
    # Avoid counting idx = 0 as possible
    # solution we are using idx != 0
    if ((temp == l or temp == r or
        (temp > l and temp < r)) and 
         idx != 0):
        temp1 += 1
  
    # Return the value of current state
    dp[(idx, sum)] = temp1
    return dp[(idx, sum)]
  
# Driver Code
if __name__ == '__main__':
      
    N = 5
    M = 22
    L = 14
    R = 16
      
    arr = [ 17, 11, 10, 8, 15 ]
  
    print(countMagicNumbers(0, 0, arr, N, M, L, R))
  
# This code is contributed by mohit kumar 29


输出:
3

时间复杂度: O(S * N),其中N是给定数组的大小而S是所有数组元素的总和。
空间复杂度: O(S * N)