给定两个正整数N和K ,任务是计算将N写成K 个非负整数之和的方法数。
例子:
Input: N = 2, K = 3
Output: 6
Explanation:
The total ways in which 2 can be split into K non-negative integers are:
1. (0, 0, 2)
2. (0, 2, 0)
3. (2, 0, 0)
4. (0, 1, 1)
5. (1, 0, 1)
6. (1, 1, 0)
Input: N = 3, K = 2
Output: 4
Explanation:
The total ways in which can be split 3 into 2 non-negative integers are:
1. (0, 3)
2. (3, 0)
3. (1, 2)
4. (2, 1)
方法:这个问题可以用动态规划解决。以下是步骤:
- 将一个二维数组初始化为dp[K+1][N+1] ,其中行对应于我们选择的元素的数量,列对应于相应的总和。
- 在上表dp[][] 中以总和为K开始填充第一行和第一列。
- 假设我们到达第 i行第 j列,即我们可以选择 i 个元素,我们需要得到总和 j。计算直到 dp[i][j] 选择第一个(i – 1) 个元素和下一个(j – x) 的方式的数量,其中 x 是第一个(i – 1) 个元素的总和。
- 重复以上步骤填充dp[][]数组。
- 值dp[n][m]将给出所需的结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
int countWays(int n, int m)
{
// Initialise dp[][] array
int dp[m + 1][n + 1];
// Only 1 way to choose the value
// with sum K
for (int i = 0; i <= n; i++) {
dp[1][i] = 1;
}
// Initialise sum
int sum;
for (int i = 2; i <= m; i++) {
for (int j = 0; j <= n; j++) {
sum = 0;
// Count the ways from previous
// states
for (int k = 0; k <= j; k++) {
sum += dp[i - 1][k];
}
// Update the sum
dp[i][j] = sum;
}
}
// Return the final count of ways
return dp[m][n];
}
// Driver Code
int main()
{
int N = 2, K = 3;
// Function call
cout << countWays(N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
static int countWays(int n, int m)
{
// Initialise dp[][] array
int [][]dp = new int[m + 1][n + 1];
// Only 1 way to choose the value
// with sum K
for(int i = 0; i <= n; i++)
{
dp[1][i] = 1;
}
// Initialise sum
int sum;
for(int i = 2; i <= m; i++)
{
for(int j = 0; j <= n; j++)
{
sum = 0;
// Count the ways from previous
// states
for(int k = 0; k <= j; k++)
{
sum += dp[i - 1][k];
}
// Update the sum
dp[i][j] = sum;
}
}
// Return the final count of ways
return dp[m][n];
}
// Driver Code
public static void main(String[] args)
{
int N = 2, K = 3;
// Function call
System.out.print(countWays(N, K));
}
}
// This code is contributed by gauravrajput1
Python3
# Python3 program for the above approach
# Function to count the number of ways
# to write N as sum of k non-negative
# integers
def countWays(n, m):
# Initialise dp[][] array
dp = [[ 0 for i in range(n + 1)]
for i in range(m + 1)]
# Only 1 way to choose the value
# with sum K
for i in range(n + 1):
dp[1][i] = 1
# Initialise sum
sum = 0
for i in range(2, m + 1):
for j in range(n + 1):
sum = 0
# Count the ways from previous
# states
for k in range(j + 1):
sum += dp[i - 1][k]
# Update the sum
dp[i][j] = sum
# Return the final count of ways
return dp[m][n]
# Driver Code
if __name__ == '__main__':
N = 2
K = 3
# Function call
print(countWays(N, K))
# This code is contributed by Mohit Kumar
C#
// C# program for the above approach
using System;
class GFG{
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
static int countWays(int n, int m)
{
// Initialise [,]dp array
int [,]dp = new int[m + 1, n + 1];
// Only 1 way to choose the value
// with sum K
for(int i = 0; i <= n; i++)
{
dp[1, i] = 1;
}
// Initialise sum
int sum;
for(int i = 2; i <= m; i++)
{
for(int j = 0; j <= n; j++)
{
sum = 0;
// Count the ways from previous
// states
for(int k = 0; k <= j; k++)
{
sum += dp[i - 1, k];
}
// Update the sum
dp[i, j] = sum;
}
}
// Return the readonly count of ways
return dp[m, n];
}
// Driver Code
public static void Main(String[] args)
{
int N = 2, K = 3;
// Function call
Console.Write(countWays(N, K));
}
}
// This code is contributed by gauravrajput1
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
int countWays(int n, int m)
{
// Initialise dp[][] array
int dp[m + 1][n + 1];
// Fill the dp[][] with sum = m
for (int i = 0; i <= n; i++) {
dp[1][i] = 1;
if (i != 0) {
dp[1][i] += dp[1][i - 1];
}
}
// Iterate the dp[][] to fill the
// dp[][] array
for (int i = 2; i <= m; i++) {
for (int j = 0; j <= n; j++) {
// Condition for first column
if (j == 0) {
dp[i][j] = dp[i - 1][j];
}
// Else fill the dp[][] with
// sum till (i, j)
else {
dp[i][j] = dp[i - 1][j];
// If reach the end, then
// return the value
if (i == m && j == n) {
return dp[i][j];
}
// Update at current index
dp[i][j] += dp[i][j - 1];
}
}
}
}
// Driver Code
int main()
{
int N = 2, K = 3;
// Function call
cout << countWays(N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
static int countWays(int n, int m)
{
// Initialise dp[][] array
int [][]dp = new int[m + 1][n + 1];
// Fill the dp[][] with sum = m
for (int i = 0; i <= n; i++)
{
dp[1][i] = 1;
if (i != 0)
{
dp[1][i] += dp[1][i - 1];
}
}
// Iterate the dp[][] to fill the
// dp[][] array
for (int i = 2; i <= m; i++)
{
for (int j = 0; j <= n; j++)
{
// Condition for first column
if (j == 0)
{
dp[i][j] = dp[i - 1][j];
}
// Else fill the dp[][] with
// sum till (i, j)
else
{
dp[i][j] = dp[i - 1][j];
// If reach the end, then
// return the value
if (i == m && j == n)
{
return dp[i][j];
}
// Update at current index
dp[i][j] += dp[i][j - 1];
}
}
}
return Integer.MIN_VALUE;
}
// Driver Code
public static void main(String[] args)
{
int N = 2, K = 3;
// Function call
System.out.print(countWays(N, K));
}
}
// This code is contributed by sapnasingh4991
Python3
# Python3 program for the above approach
# Function to count the number of ways
# to write N as sum of k non-negative
# integers
def countWays(n, m):
# Initialise dp[][] array
dp = [[0 for i in range(n + 1)]
for j in range(m + 1)]
# Fill the dp[][] with sum = m
for i in range(n + 1):
dp[1][i] = 1
if (i != 0):
dp[1][i] += dp[1][i - 1]
# Iterate the dp[][] to fill the
# dp[][] array
for i in range(2, m + 1):
for j in range(n + 1):
# Condition for first column
if (j == 0):
dp[i][j] = dp[i - 1][j]
# Else fill the dp[][] with
# sum till (i, j)
else:
dp[i][j] = dp[i - 1][j]
# If reach the end, then
# return the value
if (i == m and j == n):
return dp[i][j]
# Update at current index
dp[i][j] += dp[i][j - 1]
# Driver Code
N = 2
K = 3
# Function call
print(countWays(N, K))
# This code is contributed by ShubhamCoder
C#
// C# program for the above approach
using System;
class GFG{
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
static int countWays(int n, int m)
{
// Initialise dp[][] array
int [,]dp = new int[m + 1, n + 1];
// Fill the dp[][] with sum = m
for (int i = 0; i <= n; i++)
{
dp[1, i] = 1;
if (i != 0)
{
dp[1, i] += dp[1, i - 1];
}
}
// Iterate the dp[][] to fill the
// dp[][] array
for (int i = 2; i <= m; i++)
{
for (int j = 0; j <= n; j++)
{
// Condition for first column
if (j == 0)
{
dp[i, j] = dp[i - 1, j];
}
// Else fill the dp[][] with
// sum till (i, j)
else
{
dp[i, j] = dp[i - 1, j];
// If reach the end, then
// return the value
if (i == m && j == n)
{
return dp[i, j];
}
// Update at current index
dp[i, j] += dp[i, j - 1];
}
}
}
return Int32.MinValue;
}
// Driver Code
public static void Main()
{
int N = 2, K = 3;
// Function call
Console.Write(countWays(N, K));
}
}
// This code is contributed by Code_Mech
Javascript
输出:
6
时间复杂度: O(K*N 2 )
辅助空间复杂度: O(N*K)
优化方法:计算总和然后存储计数的想法增加了时间复杂度。我们可以通过将总和存储在上面的 dp[][] 表中来减少它。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
int countWays(int n, int m)
{
// Initialise dp[][] array
int dp[m + 1][n + 1];
// Fill the dp[][] with sum = m
for (int i = 0; i <= n; i++) {
dp[1][i] = 1;
if (i != 0) {
dp[1][i] += dp[1][i - 1];
}
}
// Iterate the dp[][] to fill the
// dp[][] array
for (int i = 2; i <= m; i++) {
for (int j = 0; j <= n; j++) {
// Condition for first column
if (j == 0) {
dp[i][j] = dp[i - 1][j];
}
// Else fill the dp[][] with
// sum till (i, j)
else {
dp[i][j] = dp[i - 1][j];
// If reach the end, then
// return the value
if (i == m && j == n) {
return dp[i][j];
}
// Update at current index
dp[i][j] += dp[i][j - 1];
}
}
}
}
// Driver Code
int main()
{
int N = 2, K = 3;
// Function call
cout << countWays(N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
static int countWays(int n, int m)
{
// Initialise dp[][] array
int [][]dp = new int[m + 1][n + 1];
// Fill the dp[][] with sum = m
for (int i = 0; i <= n; i++)
{
dp[1][i] = 1;
if (i != 0)
{
dp[1][i] += dp[1][i - 1];
}
}
// Iterate the dp[][] to fill the
// dp[][] array
for (int i = 2; i <= m; i++)
{
for (int j = 0; j <= n; j++)
{
// Condition for first column
if (j == 0)
{
dp[i][j] = dp[i - 1][j];
}
// Else fill the dp[][] with
// sum till (i, j)
else
{
dp[i][j] = dp[i - 1][j];
// If reach the end, then
// return the value
if (i == m && j == n)
{
return dp[i][j];
}
// Update at current index
dp[i][j] += dp[i][j - 1];
}
}
}
return Integer.MIN_VALUE;
}
// Driver Code
public static void main(String[] args)
{
int N = 2, K = 3;
// Function call
System.out.print(countWays(N, K));
}
}
// This code is contributed by sapnasingh4991
蟒蛇3
# Python3 program for the above approach
# Function to count the number of ways
# to write N as sum of k non-negative
# integers
def countWays(n, m):
# Initialise dp[][] array
dp = [[0 for i in range(n + 1)]
for j in range(m + 1)]
# Fill the dp[][] with sum = m
for i in range(n + 1):
dp[1][i] = 1
if (i != 0):
dp[1][i] += dp[1][i - 1]
# Iterate the dp[][] to fill the
# dp[][] array
for i in range(2, m + 1):
for j in range(n + 1):
# Condition for first column
if (j == 0):
dp[i][j] = dp[i - 1][j]
# Else fill the dp[][] with
# sum till (i, j)
else:
dp[i][j] = dp[i - 1][j]
# If reach the end, then
# return the value
if (i == m and j == n):
return dp[i][j]
# Update at current index
dp[i][j] += dp[i][j - 1]
# Driver Code
N = 2
K = 3
# Function call
print(countWays(N, K))
# This code is contributed by ShubhamCoder
C#
// C# program for the above approach
using System;
class GFG{
// Function to count the number of ways
// to write N as sum of k non-negative
// integers
static int countWays(int n, int m)
{
// Initialise dp[][] array
int [,]dp = new int[m + 1, n + 1];
// Fill the dp[][] with sum = m
for (int i = 0; i <= n; i++)
{
dp[1, i] = 1;
if (i != 0)
{
dp[1, i] += dp[1, i - 1];
}
}
// Iterate the dp[][] to fill the
// dp[][] array
for (int i = 2; i <= m; i++)
{
for (int j = 0; j <= n; j++)
{
// Condition for first column
if (j == 0)
{
dp[i, j] = dp[i - 1, j];
}
// Else fill the dp[][] with
// sum till (i, j)
else
{
dp[i, j] = dp[i - 1, j];
// If reach the end, then
// return the value
if (i == m && j == n)
{
return dp[i, j];
}
// Update at current index
dp[i, j] += dp[i, j - 1];
}
}
}
return Int32.MinValue;
}
// Driver Code
public static void Main()
{
int N = 2, K = 3;
// Function call
Console.Write(countWays(N, K));
}
}
// This code is contributed by Code_Mech
Javascript
输出:
6
时间复杂度: O(K*N)
辅助空间复杂度: O(N*K)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。