📌  相关文章
📜  number 的所有分区的元素总和,使得没有元素小于 K

📅  最后修改于: 2021-09-17 07:18:23             🧑  作者: Mango

给定一个整数 N,任务是找到这个数字的所有整数分区的总和,使得每个分区不包含任何小于 K 的整数。
例子:

方法:这个问题有一个简单的递归解决方案。首先,我们需要计算编号为 N 的有效分区的总数,使得每个分区包含大于或等于 K 的整数。因此,我们将迭代地应用我们的递归解决方案来找到具有最小整数 K、K+1 的有效分区, K+2, …, N。
我们的最终答案是N * no of有效分区,因为每个有效分区的总和等于 N。
以下是设计递归函数以查找有效分区总数的一些关键思想。

  • 如果N < K则不可能进行分区。
  • 如果N < 2*K那么只有一个分区是可能的,这就是 N 本身。
  • 我们可以以递归方式找到包含至少等于 ‘i’ 的整数(’i’ 可以是从 K 到 N)的数字分区,并将它们全部相加以获得最终答案。

用于查找有效分区数的递归函数的伪代码:

f(N,K):
       if N < K
           return 0
       if N < 2K
           return 1
       Initialize answer = 1
       FOR i from K to N
           answer = answer + f(N-i,i)
return answer 

以下是动态规划解决方案:

C++
// C++ implementation of above approach
#include 
using namespace std;
  
// Function that returns total number of valid
// partitions of integer N
long long int countPartitions(int n, int k)
{
  
      
    // Global declaration of 2D dp array
    // which will be later used for memoization
    long long int dp[201][201];
  
    // initializing 2D dp array with -1
    // we will use this 2D array for memoization
    for (int i = 0; i < n + 1; i++) {
        for (int j = 0; j < n + 1; j++) {
            dp[i][j] = -1;
        }
    }
  
    // if this subproblem is already previously
    // calculated, then directly return that answer
    if (dp[n][k] >= 0)
        return dp[n][k];
  
    // if N < K, then no valid 
    // partition is possible
    if (n < k)
        return 0;
  
    // if N is between K to 2*K then
    // there is only one
    // partition and that is the number N itself
    if (n < 2 * k)
        return 1;
  
    // Initialize answer with 1 as 
    // the number N itself
    // is always a valid partition
    long long int answer = 1;
  
    // for loop to iterate over K to N
    // and find number of
    // possible valid partitions recursively.
    for (int i = k; i < n; i++)
        answer = answer + countPartitions(n - i, i);
  
    // memoization is done by storing
    // this calculated answer
    dp[n][k] = answer;
  
    // returning number of valid partitions
    return answer;
}
  
// Driver code
int main()
{
    int n = 10, k = 3;
  
    // Printing total number of valid partitions
    cout << "Total Aggregate sum of all Valid Partitions: "
         << countPartitions(n, k) * n;
  
    return 0;
}


Java
// Java implementation of
// above approach
class GFG
{
// Function that returns
// total number of valid
// partitions of integer N
static long countPartitions(int n, int k)
{
  
    // Global declaration of 2D
    // dp array which will be 
    // later used for memoization
    long[][] dp = new long[201][201];
  
    // initializing 2D dp array 
    // with -1 we will use this 
    // 2D array for memoization
    for (int i = 0; i < n + 1; i++)
    {
        for (int j = 0; j < n + 1; j++)
        {
            dp[i][j] = -1;
        }
    }
  
    // if this subproblem is already 
    // previously calculated, then 
    // directly return that answer
    if (dp[n][k] >= 0)
        return dp[n][k];
  
    // if N < K, then no valid 
    // partition is possible
    if (n < k)
        return 0;
  
    // if N is between K to 2*K 
    // then there is only one
    // partition and that is 
    // the number N itself
    if (n < 2 * k)
        return 1;
  
    // Initialize answer with 1
    // as the number N itself
    // is always a valid partition
    long answer = 1;
  
    // for loop to iterate over 
    // K to N and find number of
    // possible valid partitions
    // recursively.
    for (int i = k; i < n; i++)
        answer = answer + 
                 countPartitions(n - i, i);
  
    // memoization is done by storing
    // this calculated answer
    dp[n][k] = answer;
  
    // returning number of
    // valid partitions
    return answer;
}
  
// Driver code
public static void main(String[] args)
{
    int n = 10, k = 3;
  
    // Printing total number
    // of valid partitions
    System.out.println("Total Aggregate sum of " + 
                       "all Valid Partitions: " + 
                       countPartitions(n, k) * n);
}
}
  
// This code is contributed by mits


Python3
# Python3 implementation of above approach 
  
# Function that returns total number of valid 
# partitions of integer N 
def countPartitions(n, k): 
  
    # Global declaration of 2D dp array 
    # which will be later used for memoization 
    dp = [[0] * 201] * 201
  
    # Initializing 2D dp array with -1 
    # we will use this 2D array for memoization 
    for i in range(n + 1):
        for j in range(n + 1):
            dp[i][j] = -1
          
    # If this subproblem is already previously 
    # calculated, then directly return that answer 
    if (dp[n][k] >= 0):
        return dp[n][k] 
  
    # If N < K, then no valid 
    # partition is possible 
    if (n < k) :
        return 0
  
    # If N is between K to 2*K then 
    # there is only one partition 
    # and that is the number N itself 
    if (n < 2 * k):
        return 1
  
    # Initialize answer with 1 as 
    # the number N itself 
    # is always a valid partition 
    answer = 1
  
    # For loop to iterate over K to N 
    # and find number of possible valid 
    # partitions recursively. 
    for i in range(k, n): 
        answer = (answer + 
                  countPartitions(n - i, i)) 
  
    # Memoization is done by storing 
    # this calculated answer 
    dp[n][k] = answer 
  
    # Returning number of valid partitions 
    return answer 
  
# Driver code 
n = 10
k = 3
  
# Printing total number of valid partitions 
print("Total Aggregate sum of all "
      "Valid Partitions: ", 
      countPartitions(n, k) * n)
  
# This code is contributed by sanjoy_62


C#
// C# implementation of above approach
using System; 
    
class GFG 
{ 
    // Function that returns total number of valid 
    // partitions of integer N 
    public static long countPartitions(int n, int k) 
    { 
        
        // Global declaration of 2D dp array 
        // which will be later used for memoization 
        long[,] dp = new long[201,201]; 
        
        // initializing 2D dp array with -1 
        // we will use this 2D array for memoization 
        for (int i = 0; i < n + 1; i++) { 
            for (int j = 0; j < n + 1; j++) { 
                dp[i,j] = -1; 
            } 
        } 
        
        // if this subproblem is already previously 
        // calculated, then directly return that answer 
        if (dp[n,k] >= 0) 
            return dp[n,k]; 
        
        // if N < K, then no valid  
        // partition is possible 
        if (n < k) 
            return 0; 
        
        // if N is between K to 2*K then 
        // there is only one 
        // partition and that is the number N itself 
        if (n < 2 * k) 
            return 1; 
        
        // Initialize answer with 1 as  
        // the number N itself 
        // is always a valid partition 
        long answer = 1; 
        
        // for loop to iterate over K to N 
        // and find number of 
        // possible valid partitions recursively. 
        for (int i = k; i < n; i++) 
            answer = answer + countPartitions(n - i, i); 
        
        // memoization is done by storing 
        // this calculated answer 
        dp[n,k] = answer; 
        
        // returning number of valid partitions 
        return answer; 
    } 
        
    // Driver code  
    static void Main() 
    { 
        int n = 10, k = 3; 
    
        // Printing total number of valid partitions 
        Console.Write("Total Aggregate sum of all Valid Partitions: " + countPartitions(n, k) * n); 
    }
    //This code is contributed by DrRoot_
}


输出:
Total Aggregate sum of all Valid Partitions: 50

时间复杂度: O(N 2 )