给定两个整数N和K ,任务是找到将N表示为[1, K]范围内正整数之和的方法总数,其中每个整数可以多次选择。
例子:
Input: N = 8, K = 2
Output: 5
Explanation: All possible ways of representing N as sum of positive integers less than or equal to K are:
- {1, 1, 1, 1, 1, 1, 1, 1}, the sum is 8.
- {2, 1, 1, 1, 1, 1, 1}, the sum is 8.
- {2, 2, 1, 1, 1, 1}, the sum is 8.
- 2, 2, 2, 1, 1}, the sum is 8.
- {2, 2, 2, 2}}, the sum is 8.
Therefore, the total number of ways is 5.
Input: N = 2, K = 2
Output: 2
朴素方法:解决给定问题的最简单方法是生成在[1, K]范围内选择整数的所有可能组合,并计算总和为N 的那些组合。
时间复杂度: O(K N )
辅助空间: O(1)
高效方法:上述方法具有重叠子问题和最优子结构。因此,为了优化,需要基于以下观察进行动态规划:
- 考虑到dp[i]将表示i的方式总数存储为[1, K]范围内整数的总和,那么状态转换可以定义为:
- 对于[1, K]范围内的i和[1, N]范围内的每个j
- dp[j] 的值等于(dp[j]+ dp[j – i]) ,对于所有j ≥ i 。
请按照以下步骤解决问题:
- 初始化一个数组,比如dp[] ,所有元素都为0 ,以存储所有递归状态。
- 将dp[0]初始化为1 。
- 现在,使用变量i迭代范围[1, K]并执行以下步骤:
- 迭代范围[1, N] ,使用变量j ,并将dp[j]的值更新为dp[j]+ dp[j – i] ,如果j ≥ i 。
- 完成以上步骤后,打印dp[N]的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the total number of
// ways to represent N as the sum of
// integers over the range [1, K]
int NumberOfways(int N, int K)
{
// Initialize a list
vector dp(N + 1, 0);
// Update dp[0] to 1
dp[0] = 1;
// Iterate over the range [1, K + 1]
for (int row = 1; row < K + 1; row++)
{
// Iterate over the range [1, N + 1]
for (int col = 1; col < N + 1; col++)
{
// If col is greater
// than or equal to row
if (col >= row)
// Update current
// dp[col] state
dp[col] = dp[col] + dp[col - row];
}
}
// Return the total number of ways
return(dp[N]);
}
// Driver Code
int main()
{
int N = 8;
int K = 2;
cout << (NumberOfways(N, K));
}
// This code is contributed by mohit kumar 29.
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find the total number of
// ways to represent N as the sum of
// integers over the range [1, K]
static int NumberOfways(int N, int K)
{
// Initialize a list
int[] dp = new int[N + 1];
// Update dp[0] to 1
dp[0] = 1;
// Iterate over the range [1, K + 1]
for(int row = 1; row < K + 1; row++)
{
// Iterate over the range [1, N + 1]
for(int col = 1; col < N + 1; col++)
{
// If col is greater
// than or equal to row
if (col >= row)
// Update current
// dp[col] state
dp[col] = dp[col] + dp[col - row];
}
}
// Return the total number of ways
return(dp[N]);
}
// Driver code
public static void main(String[] args)
{
// Given inputs
int N = 8;
int K = 2;
System.out.println(NumberOfways(N, K));
}
}
// This code is contributed by offbeat
Python
# Python program for the above approach
# Function to find the total number of
# ways to represent N as the sum of
# integers over the range [1, K]
def NumberOfways(N, K):
# Initialize a list
dp = [0] * (N + 1)
# Update dp[0] to 1
dp[0] = 1
# Iterate over the range [1, K + 1]
for row in range(1, K + 1):
# Iterate over the range [1, N + 1]
for col in range(1, N + 1):
# If col is greater
# than or equal to row
if (col >= row):
# Update current
# dp[col] state
dp[col] = dp[col] + dp[col - row]
# Return the total number of ways
return(dp[N])
# Driver Code
N = 8
K = 2
print(NumberOfways(N, K))
C#
// C# program for the above approach
using System;
class GFG
{
// Function to find the total number of
// ways to represent N as the sum of
// integers over the range [1, K]
static int NumberOfways(int N, int K)
{
// Initialize a list
int[] dp = new int[(N + 1)];
// Update dp[0] to 1
dp[0] = 1;
// Iterate over the range [1, K + 1]
for (int row = 1; row < K + 1; row++) {
// Iterate over the range [1, N + 1]
for (int col = 1; col < N + 1; col++) {
// If col is greater
// than or equal to row
if (col >= row)
// Update current
// dp[col] state
dp[col] = dp[col] + dp[col - row];
}
}
// Return the total number of ways
return (dp[N]);
}
// Driver Code
public static void Main()
{
int N = 8;
int K = 2;
Console.WriteLine(NumberOfways(N, K));
}
}
// This code is contributed by ukasp.
Javascript
输出:
5
时间复杂度: O(N * K)
辅助空间: O(N)