📌  相关文章
📜  使用模 H 连续添加 Array 元素时,最大限度地增加 L 和 R 之间的值的出现次数

📅  最后修改于: 2021-09-17 16:08:17             🧑  作者: Mango

给定一个具有N 个正整数和一个正整数H的数组arr[] ,任务是在将arr[i]arr[i] – 1 添加X 时计算范围[L, R]中的值的最大出现次数(最初为 0)。整数X必须始终小于H 。如果它大于H ,则用X % H替换X

例子:

方法:这个问题可以用动态规划解决。维护一个表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


Javascript


输出:
3

时间复杂度: O(N * H)

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