📜  [L, R] 范围内最多 N 位的排序数字的总数(华丽的项链组合问题)

📅  最后修改于: 2021-09-22 10:20:46             🧑  作者: Mango

给定三个整数N、LR ,任务是打印形成最多N颗珍珠项链的方法总数,使珍珠的值在[L, R]范围内并按升序排列.

例子:

方法:根据以下观察可以解决给定的问题:

  1. 该问题可以使用带有前缀和的 2 状态动态规划来解决。
  2. 假设Dp(i, j)存储形成大小为i的项链的方法计数,珍珠的值在范围[L, j] 内。
  3. 那么第i位置的过渡状态可以定义为:
    1. 对于[L, R]范围内的每个值j
      1. Dp(i, j) = Dp(i – 1, L) + Dp(i – 1, L + 1), …, Dp(i – 1, j – 1)+ Dp(i – 1, j)
  4. 可以通过对每个i使用前缀和来优化上述转换:
    1. Dp(i, j) = Dp(i, L) + Dp(i, L + 1) +…+ Dp(i, j – 1) + Dp(i, j)
  5. 因此,现在可以将转换定义为:
    1. Dp(i, j) = Dp(i-1, j) + Dp(i, j-1)

请按照以下步骤解决问题:

  • 初始化一个变量,比如ans0 ,以存储结果。
  • 初始化一个二维数组,比如维度N * (R – L + 1) 的Dp[][]0以存储所有 DP 状态。
  • 使用变量i在范围[0, N – 1] 上迭代并分配Dp[i][0] = 1。
  • 使用变量i在范围[1, R – L] 上迭代并将Dp[0][i] 更新Dp[0][i]= Dp[0][i – 1]+1。
  • Dp[0][R – L]分配给ans。
  • 使用变量i在范围[1, N – 1] 上迭代并执行以下操作:
    • 使用变量j在范围[1, R – L] 上迭代并将Dp[i][j] 更新Dp[i][j] = Dp[i][j – 1] + Dp[i – 1 ][j]。
    • ans增加Dp[i][R – L]。
  • 最后,完成上述步骤后,打印ans

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to count total number of ways
int Count(int N, int L, int R)
{
    // Stores all DP-states
    vector > dp(N,
                            vector(R - L + 1, 0));
    // Stores the result
    int ans = 0;
 
    // Traverse the range [0, N]
    for (int i = 0; i < N; i++) {
        dp[i][0] = 1;
    }
    // Traverse the range [1, R - L]
    for (int i = 1; i < dp[0].size(); i++) {
 
        // Update dp[i][j]
        dp[0][i] = dp[0][i - 1] + 1;
    }
 
    // Assign dp[0][R-L] to ans
    ans = dp[0][R - L];
 
    // Traverse the range [1, N]
    for (int i = 1; i < N; i++) {
 
        // Traverse the range [1, R - L]
        for (int j = 1; j < dp[0].size(); j++) {
 
            // Update dp[i][j]
            dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
        }
 
        // Increment ans by dp[i-1][j]
        ans += dp[i][R - L];
    }
 
    // Return ans
    return ans;
}
 
// Driver Code
int main()
{
    // Input
    int N = 3;
    int L = 6;
    int R = 9;
 
    // Function call
    cout << Count(N, L, R);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function to count total number of ways
static int Count(int N, int L, int R)
{
     
    // Stores all DP-states
    int[][] dp = new int[N][R - L + 1];
     
    // Stores the result
    int ans = 0;
 
    // Traverse the range [0, N]
    for(int i = 0; i < N; i++)
    {
        dp[i][0] = 1;
    }
     
    // Traverse the range [1, R - L]
    for(int i = 1; i < dp[0].length; i++)
    {
         
        // Update dp[i][j]
        dp[0][i] = dp[0][i - 1] + 1;
    }
 
    // Assign dp[0][R-L] to ans
    ans = dp[0][R - L];
 
    // Traverse the range [1, N]
    for(int i = 1; i < N; i++)
    {
         
        // Traverse the range [1, R - L]
        for(int j = 1; j < dp[0].length; j++)
        {
             
            // Update dp[i][j]
            dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
        }
 
        // Increment ans by dp[i-1][j]
        ans += dp[i][R - L];
    }
 
    // Return ans
    return ans;
}
 
// Driver Code
public static void main(String args[])
{
     
    // Input
    int N = 3;
    int L = 6;
    int R = 9;
 
    // Function call
    System.out.println(Count(N, L, R));
}
}
 
// This code is contributed by avijitmondal1998


Python3
# Python3 program for the above approach
 
# Function to count total number of ways
def Count(N, L, R):
     
    # Stores all DP-states
    dp = [[0 for i in range(R - L + 1)]
             for i in range(N)]
              
    # Stores the result
    ans = 0
 
    # Traverse the range [0, N]
    for i in range(N):
        dp[i][0] = 1
 
    # Traverse the range [1, R - L]
    for i in range(1, len(dp[0])):
         
        # Update dp[i][j]
        dp[0][i] = dp[0][i - 1] + 1
 
    # Assign dp[0][R-L] to ans
    ans = dp[0][R - L]
 
    # Traverse the range [1, N]
    for i in range(1, N):
         
        # Traverse the range [1, R - L]
        for j in range(1, len(dp[0])):
             
            # Update dp[i][j]
            dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
 
        # Increment ans by dp[i-1][j]
        ans += dp[i][R - L]
 
    # Return ans
    return ans
 
# Driver Code
if __name__ == '__main__':
     
    # Input
    N = 3
    L = 6
    R = 9
 
    # Function call
    print(Count(N, L, R))
     
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
 
class GFG{
 
// Function to count total number of ways
static int Count(int N, int L, int R)
{
     
    // Stores all DP-states
    int[,] dp = new int[N, R - L + 1];
 
    // Stores the result
    int ans = 0;
 
    // Traverse the range [0, N]
    for(int i = 0; i < N; i++)
    {
        dp[i, 0] = 1;
    }
 
    // Traverse the range [1, R - L]
    for(int i = 1; i < dp.GetLength(1); i++)
    {
         
        // Update dp[i][j]
        dp[0, i] = dp[0, i - 1] + 1;
    }
 
    // Assign dp[0][R-L] to ans
    ans = dp[0, R - L];
 
    // Traverse the range [1, N]
    for(int i = 1; i < N; i++)
    {
         
        // Traverse the range [1, R - L]
        for(int j = 1; j < dp.GetLength(1); j++)
        {
             
            // Update dp[i][j]
            dp[i, j] = dp[i - 1, j] + dp[i, j - 1];
        }
 
        // Increment ans by dp[i-1][j]
        ans += dp[i, R - L];
    }
 
    // Return ans
    return ans;
}
 
// Driver Code
public static void Main()
{
     
    // Input
    int N = 3;
    int L = 6;
    int R = 9;
 
    // Function call
    Console.Write(Count(N, L, R));
}
}
 
// This code is contributed by ukasp


Javascript


输出
34

时间复杂度: O(N * (R – L))
辅助空间: O(N * (R – L))

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