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

📅  最后修改于: 2021-09-17 06:58:50             🧑  作者: Mango

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

  • arr[i]arr[i] – 1 添加S
  • 将 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. 找出所有可能的组合后,返回S%M位于 [L, R]范围内的值的计数。

下面是上述方法的实现:

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)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。