给定一个由N 个整数和整数M, L, R 组成的数组 arr[] 。考虑一个变量S (最初为0 )。任务是在对给定数组中的每个元素执行以下操作后,找到位于[L, R]范围内的 S % M值的最大计数:
- 将arr[i]或arr[i] – 1 添加到S 。
- 将 S 更改为 S % M 。
例子:
Input: arr[] = {17, 11, 10, 8, 15}, M = 22, L = 14, R = 16
Output: 3
Explanation:
Initially S = 0,
Step 1: Choose, arr[0] – 1 = 16 and add it to S = 16 and S%M = 16. Therefore, count = 1
Step 2: Choose, arr[1] = 11 and add it to S = 16 + 11 = 27 and S%M = 5. Therefore, count = 1
Step 3: Choose, arr[2] = 10 and add it to S = 16 + 10 +11 = 37 and S%M = 15. Therefore, count = 2
Step 4: Choose, arr[3] = 8 and add it to S = 16 + 10 + 11 + 8 = 45 and S%M = 1. Therefore, count = 2
Step 5: Choose, arr[4] = 15 and add it to S = 16 + 10 + 11 + 8 + 15 = 60 and S%M = 16. Therefore, count = 3.
Hence the maximum count is 3.
Input: arr[] = {23, 1}, M = 24, L = 21, R = 23
Output: 2
朴素的方法:最简单的方法是遍历给定的数组arr[]并将arr[i]或arr[i – 1] 添加到给定的S并检查S%M是否在 [L, R]范围内。由于有两种可能性可以选择给定的数字。因此,使用递归递归获取S%M值的最大计数位于 [L, R]范围内。
时间复杂度: O(2 N )
辅助空间: O(N)
有效的方法:优化上述方法的想法是使用动态规划来存储重叠的子问题,然后找到 S%M 的最大计数位于[L, R]范围内。请按照以下步骤解决问题:
- 初始化 unordered_map dp以存储具有重叠子问题的状态值。
- 将总和初始化为0 ,然后递归地将arr[i] 或 arr[i] – 1值添加到总和S 。
- 在每一步,检查S%M是否在 [L, R]范围内。如果它在范围内,则计算该值并将上述地图dp中的当前状态更新为 1。否则更新为0 。
- 找出所有可能的组合后,返回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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live