给定具有N个正整数和H个正整数的数组arr [] ,任务是在将arr [i]或arr [i] – 1加到X时,计算一个值在[L,R]范围内的最大出现次数(最初为0)。整数X必须始终小于H。如果它大于H ,则用X%H替换X
例子:
Input: arr = {16, 17, 14, 20, 20, 11, 22}, H = 24, L = 21, R = 23
Output: 3
Explanation:
Initially X = 0.
Then add arr[0] – 1 to X, now the X is 15. This X is not good.
Then add arr[1] – 1 to X, now the X is 15 + 16 = 31. 31 % H = 7. This X is also not good.
Then add arr[2] to X, now the X is 7 + 14 = 21. This X is good.
Then add arr[3] – 1 to X, now the X is (21 + 19) % H = 16. This X is not good.
Then add arr[4] to X, now the X is (16 + 20) % H = 12. This X is not good.
Then add arr[5] to X, now the X is 12 + 11 = 23. This X is good.
Then add arr[6] to X, now the X is 23 + 22 = 21. This X is also good.
So, the maximum number of good X in the example is 3.
Input: arr = {1, 2, 3}, H = 5, L = 1, R = 2
Output: 2
方法:可以通过动态编程解决此问题。维持一个表dp [N + 1] [H] ,该表表示在添加多达i个元素时在[L,R]范围内一个元素的最大出现次数。对于每个第i个索引,通过将arr [i]和arr [i] – 1相加来计算可获得的最大可能频率。一次,为所有索引计算后,从dp [] []矩阵的最后一行中找到最大值。
下面是上述方法的实现:
C++
// C++ implementation of the
// above approach
#include
using namespace std;
// Function that prints the number
// of times X gets a value
// between L and R
void goodInteger(int arr[], int n,
int h, int l, int r)
{
vector > dp(
n + 1,
vector(h, -1));
// Base condition
dp[0][0] = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < h; j++) {
// Condition if X can be made
// equal to j after i additions
if (dp[i][j] != -1) {
// Compute value of X
// after adding arr[i]
int h1 = (j + arr[i]) % h;
// Compute value of X after
// adding arr[i] - 1
int h2 = (j + arr[i] - 1) % h;
// Update dp as the maximum value
dp[i + 1][h1]
= max(dp[i + 1][h1],
dp[i][j]
+ (h1 >= l
&& h1 <= r));
dp[i + 1][h2]
= max(dp[i + 1][h2],
dp[i][j]
+ (h2 >= l
&& h2 <= r));
}
}
}
int ans = 0;
// Compute maximum answer from all
// possible cases
for (int i = 0; i < h; i++) {
if (dp[n][i] != -1)
ans = max(ans, dp[n][i]);
}
// Printing maximum good occurrence of X
cout << ans << "\n";
}
// Driver Code
int main()
{
int A[] = { 16, 17, 14, 20, 20, 11, 22 };
int H = 24;
int L = 21;
int R = 23;
int size = sizeof(A) / sizeof(A[0]);
goodInteger(A, size, H, L, R);
return 0;
}
Java
// Java implementation of the
// above approach
class GFG{
// Function that prints the number
// of times X gets a value
// between L and R
static void goodInteger(int arr[], int n,
int h, int l, int r)
{
int [][]dp = new int[n + 1][h];
for(int i = 0; i < n; i++)
for(int j = 0; j < h; j++)
dp[i][j] = -1;
// Base condition
dp[0][0] = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < h; j++)
{
// Condition if X can be made
// equal to j after i additions
if (dp[i][j] != -1)
{
// Compute value of X
// after adding arr[i]
int h1 = (j + arr[i]) % h;
// Compute value of X after
// adding arr[i] - 1
int h2 = (j + arr[i] - 1) % h;
// Update dp as the maximum value
dp[i + 1][h1] = Math.max(dp[i + 1][h1],
dp[i][j] +
((h1 >= l &&
h1 <= r) ?
1 : 0));
dp[i + 1][h2] = Math.max(dp[i + 1][h2],
dp[i][j] +
((h2 >= l &&
h2 <= r) ?
1 : 0));
}
}
}
int ans = 0;
// Compute maximum answer from all
// possible cases
for(int i = 0; i < h; i++)
{
if (dp[n][i] != -1)
ans = Math.max(ans, dp[n][i]);
}
// Printing maximum good occurrence of X
System.out.print(ans + "\n");
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 16, 17, 14, 20, 20, 11, 22 };
int H = 24;
int L = 21;
int R = 23;
int size = A.length;
goodInteger(A, size, H, L, R);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the above approach
# Function that prints the number
# of times X gets a value
# between L and R
def goodInteger(arr, n, h, l, r):
dp = [[-1 for i in range(h)]
for j in range(n + 1)]
# Base condition
dp[0][0] = 0
for i in range(n):
for j in range(h):
# Condition if X can be made
# equal to j after i additions
if(dp[i][j] != -1):
# Compute value of X
# after adding arr[i]
h1 = (j + arr[i]) % h
# Compute value of X after
# adding arr[i] - 1
h2 = (j + arr[i] - 1) % h
# Update dp as the maximum value
dp[i + 1][h1] = max(dp[i + 1][h1],
dp[i][j] +
(h1 >= l and h1 <= r))
dp[i + 1][h2] = max(dp[i + 1][h2],
dp[i][j] +
(h2 >= l and h2 <= r))
ans = 0
# Compute maximum answer from all
# possible cases
for i in range(h):
if(dp[n][i] != -1):
ans = max(ans, dp[n][i])
# Printing maximum good occurrence of X
print(ans)
# Driver Code
if __name__ == '__main__':
A = [ 16, 17, 14, 20, 20, 11, 22 ]
H = 24
L = 21
R = 23
size = len(A)
goodInteger(A, size, H, L, R)
# This code is contributed by Shivam Singh
C#
// C# implementation of the
// above approach
using System;
class GFG{
// Function that prints the number
// of times X gets a value
// between L and R
static void goodint(int []arr, int n,
int h, int l, int r)
{
int [,]dp = new int[n + 1, h];
for(int i = 0; i < n; i++)
for(int j = 0; j < h; j++)
dp[i, j] = -1;
// Base condition
dp[0, 0] = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < h; j++)
{
// Condition if X can be made
// equal to j after i additions
if (dp[i, j] != -1)
{
// Compute value of X
// after adding arr[i]
int h1 = (j + arr[i]) % h;
// Compute value of X after
// adding arr[i] - 1
int h2 = (j + arr[i] - 1) % h;
// Update dp as the maximum value
dp[i + 1, h1] = Math.Max(dp[i + 1, h1],
dp[i, j] +
((h1 >= l &&
h1 <= r) ?
1 : 0));
dp[i + 1, h2] = Math.Max(dp[i + 1, h2],
dp[i, j] +
((h2 >= l &&
h2 <= r) ?
1 : 0));
}
}
}
int ans = 0;
// Compute maximum answer from all
// possible cases
for(int i = 0; i < h; i++)
{
if (dp[n, i] != -1)
ans = Math.Max(ans, dp[n, i]);
}
// Printing maximum good occurrence of X
Console.Write(ans + "\n");
}
// Driver Code
public static void Main(String[] args)
{
int []A = { 16, 17, 14, 20, 20, 11, 22 };
int H = 24;
int L = 21;
int R = 23;
int size = A.Length;
goodint(A, size, H, L, R);
}
}
// This code is contributed by Rajput-Ji
3
时间复杂度: O(N * H)