给定数目N和两个阵列ARR1 []和长度为4的阵列ARR1 []的ARR2 []表示的1,5,10,和20以及ARR2 []面额表示1,5,10面额的计, 和 20分别。任务是找到多少种方法,我们可以用有限的面额将它们加起来为N。
例子:
Input: arr1[] = {1, 5, 10, 20}, arr2[] = {6, 4, 3, 5}, N = 123
Output: 5
Explanation:
There are 5 ways to sum up to 123 with the given denomination of coins.
Input: arr1[] = {1, 5, 10, 20}, arr2[] = {1, 3, 2, 1}, N = 50
Output: 1
Explanation:
There is only 1 way to sum up to 50 with the given denomination of coins.
朴素的方法:让面额的数量用 A、B、C 和 D 表示。朴素的方法是运行嵌套循环。每个循环将参考每种面额的硬币数量。通过等式求出使 N 所需的每种面额的硬币数量:
(a * 1) + (b * 5) + (c * 10) + (d * 20)) == N
where 0 <= a <= A, 0 &<= b <= B, 0 <= c <= C, 0 <= d <= D and N is the total amount.
时间复杂度: O(N 4 )
辅助空间: O(1)
更好的方法:我们可以通过向循环添加一些额外的边界来优化上述朴素的方法,这将减少一些计算。通过观察,我们可以通过从 N 中删除面额为 1 的硬币来丢弃一个循环并检查以下不等式是否成立,从而轻松降低复杂性:
(N – A) <= (b * 5 + c * 10 + d * 20) <= N
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the number of
// ways to sum up a total of N
// from limited denominations
int calculateWays(int arr1[], int arr2[],
int N)
{
// Store the count of denominations
int A = arr2[0], B = arr2[1];
int C = arr2[2], D = arr2[3];
// Stores the final result
int ans = 0;
// As one of the denominations is
// rupee 1, so we can reduce the
// computation by checking the
// equality for N-(A*1) = N-A
for (int b = 0;
b <= B && b * 5 <= (N); b++)
for (int c = 0;
c <= C
&& b * 5 + c * 10 <= (N);
c++)
for (int d = 0;
d <= D
&& b * 5 + c * 10 + d * 20 <= (N);
d++)
if ((b * 5) + (c * 10)
+ (d * 20)
>= (N - A))
// Increment the count
// for number of ways
ans++;
return ans;
}
// Driver Code
int main()
{
// Given Denominations
int N = 123;
int arr1[] = { 1, 5, 10, 20 };
int arr2[] = { 6, 4, 3, 5 };
// Function Call
cout << calculateWays(arr1, arr2, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find the number of
// ways to sum up a total of N
// from limited denominations
static int calculateWays(int arr1[], int arr2[],
int N)
{
// Store the count of denominations
int A = arr2[0], B = arr2[1];
int C = arr2[2], D = arr2[3];
// Stores the final result
int ans = 0;
// As one of the denominations is
// rupee 1, so we can reduce the
// computation by checking the
// equality for N-(A*1) = N-A
for(int b = 0;
b <= B && b * 5 <= (N); b++)
for(int c = 0;
c <= C && b * 5 + c * 10 <= (N);
c++)
for(int d = 0;
d <= D &&
b * 5 + c * 10 + d * 20 <= (N);
d++)
if ((b * 5) + (c * 10) +
(d * 20) >= (N - A))
// Increment the count
// for number of ways
ans++;
return ans;
}
// Driver Code
public static void main(String[] args)
{
// Given denominations
int N = 123;
int arr1[] = { 1, 5, 10, 20 };
int arr2[] = { 6, 4, 3, 5 };
// Function call
System.out.print(calculateWays(arr1, arr2, N));
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 program for the above approach
# Function to find the number of
# ways to sum up a total of N
# from limited denominations
def calculateWays(arr1, arr2, N):
# Store the count of denominations
A = arr2[0]
B = arr2[1]
C = arr2[2]
D = arr2[3]
# Stores the final result
ans, b, c, d = 0, 0, 0, 0
# As one of the denominations is
# rupee 1, so we can reduce the
# computation by checking the
# equality for N-(A*1) = N-A
while b <= B and b * 5 <= (N):
c = 0
while (c <= C and
b * 5 + c * 10 <= (N)):
d = 0
while (d <= D and
b * 5 + c * 10 +
d * 20 <= (N)):
if ((b * 5) + (c * 10) +
(d * 20) >= (N - A)):
# Increment the count
# for number of ways
ans += 1
d += 1
c += 1
b += 1
return ans
# Driver Code
if __name__ == '__main__':
# Given Denominations
N = 123
arr1 = [ 1, 5, 10, 20 ]
arr2 = [ 6, 4, 3, 5 ]
# Function Call
print(calculateWays(arr1, arr2, N))
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG{
// Function to find the number of
// ways to sum up a total of N
// from limited denominations
static int calculateWays(int []arr1, int []arr2,
int N)
{
// Store the count of denominations
int A = arr2[0], B = arr2[1];
int C = arr2[2], D = arr2[3];
// Stores the readonly result
int ans = 0;
// As one of the denominations is
// rupee 1, so we can reduce the
// computation by checking the
// equality for N-(A*1) = N-A
for(int b = 0;
b <= B && b * 5 <= (N); b++)
for(int c = 0;
c <= C && b * 5 + c * 10 <= (N);
c++)
for(int d = 0;
d <= D &&
b * 5 + c * 10 + d * 20 <= (N);
d++)
if ((b * 5) + (c * 10) +
(d * 20) >= (N - A))
// Increment the count
// for number of ways
ans++;
return ans;
}
// Driver Code
public static void Main(String[] args)
{
// Given denominations
int N = 123;
int []arr1 = { 1, 5, 10, 20 };
int []arr2 = { 6, 4, 3, 5 };
// Function call
Console.Write(calculateWays(arr1, arr2, N));
}
}
// This code is contributed by PrinciRaj1992
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
int ways[1010];
// Function to find the number of
// ways to sum up a total of N
// from limited denominations
int calculateWays(int arr1[], int arr2[],
int N)
{
// Store the count of denominations
int A = arr2[0], B = arr2[1];
int C = arr2[2], D = arr2[3];
// Stores the final result
int ans = 0;
// L1 : Incrementing the values
// with indices with denomination
// (a * 1 + b * 5)
// This will give the number of coins
// for all combinations of coins
// with value 1 and 5
for (int b = 0;
b <= B && b * 5 <= N; b++) {
for (int a = 0;
a <= A
&& a * 1 + b * 5 <= N;
a++) {
ways[a + b * 5]++;
}
}
// L2 will sum the values of those
// indices of ways[] which is equal
// to (N - (c * 10 + d * 20))
for (int c = 0;
c <= C && c * 10 <= (N); c++) {
for (int d = 0;
d <= D
&& c * 10 + d * 20 <= (N);
d++) {
ans += ways[N - c * 10 - d * 20];
}
}
// Return the final count
return ans;
}
// Driver Code
int main()
{
// Given Denominations
int N = 123;
int arr1[] = { 1, 5, 10, 20 };
int arr2[] = { 6, 4, 3, 5 };
// Function Call
cout << calculateWays(arr1, arr2, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static int []ways = new int[1010];
// Function to find the number of
// ways to sum up a total of N
// from limited denominations
static int calculateWays(int arr1[], int arr2[],
int N)
{
// Store the count of denominations
int A = arr2[0], B = arr2[1];
int C = arr2[2], D = arr2[3];
// Stores the final result
int ans = 0;
// L1 : Incrementing the values
// with indices with denomination
// (a * 1 + b * 5)
// This will give the number of coins
// for all combinations of coins
// with value 1 and 5
for(int b = 0;
b <= B && b * 5 <= N; b++)
{
for(int a = 0;
a <= A && a * 1 + b * 5 <= N;
a++)
{
ways[a + b * 5]++;
}
}
// L2 will sum the values of those
// indices of ways[] which is equal
// to (N - (c * 10 + d * 20))
for(int c = 0;
c <= C && c * 10 <= (N); c++)
{
for(int d = 0;
d <= D && c * 10 + d * 20 <= (N);
d++)
{
ans += ways[N - c * 10 - d * 20];
}
}
// Return the final count
return ans;
}
// Driver Code
public static void main(String[] args)
{
// Given denominations
int N = 123;
int arr1[] = { 1, 5, 10, 20 };
int arr2[] = { 6, 4, 3, 5 };
// Function call
System.out.print(calculateWays(arr1, arr2, N));
}
}
// This code is contributed by Princi Singh
Python3
# Python3 program for
# the above approach
ways = [0 for i in range(1010)];
# Function to find the number of
# ways to sum up a total of N
# from limited denominations
def calculateWays(arr1, arr2, N):
# Store the count of denominations
A = arr2[0]; B = arr2[1];
C = arr2[2]; D = arr2[3];
# Stores the final result
ans = 0;
# L1 : Incrementing the values
# with indices with denomination
# (a * 1 + b * 5)
# This will give the number of coins
# for all combinations of coins
# with value 1 and 5
for b in range(0, B + 1):
if(b * 5 > N):
break;
for a in range(0, A + 1):
if(a + b * 5 > N):
break;
ways[a + b * 5] += 5;
# L2 will sum the values of those
# indices of ways which is equal
# to (N - (c * 10 + d * 20))
for c in range(0, C):
if(c * 10 > N):
break;
for d in range(0, D):
if(c * 10 + d * 20 > N):
break;
ans += ways[N - c * 10 - d * 20];
# Return the final count
return ans;
# Driver Code
if __name__ == '__main__':
# Given denominations
N = 123;
arr1 = [1, 5, 10, 20];
arr2 = [6, 4, 3, 5];
# Function call
print(calculateWays(arr1, arr2, N));
# This code is contributed by gauravrajput1
C#
// C# program for the above approach
using System;
class GFG{
static int []ways = new int[1010];
// Function to find the number of
// ways to sum up a total of N
// from limited denominations
static int calculateWays(int []arr1, int []arr2,
int N)
{
// Store the count of denominations
int A = arr2[0], B = arr2[1];
int C = arr2[2], D = arr2[3];
// Stores the readonly result
int ans = 0;
// L1 : Incrementing the values
// with indices with denomination
// (a * 1 + b * 5)
// This will give the number of coins
// for all combinations of coins
// with value 1 and 5
for(int b = 0;
b <= B && b * 5 <= N; b++)
{
for(int a = 0;
a <= A && a * 1 + b * 5 <= N;
a++)
{
ways[a + b * 5]++;
}
}
// L2 will sum the values of those
// indices of ways[] which is equal
// to (N - (c * 10 + d * 20))
for(int c = 0;
c <= C && c * 10 <= (N); c++)
{
for(int d = 0;
d <= D && c * 10 + d * 20 <= (N);
d++)
{
ans += ways[N - c * 10 - d * 20];
}
}
// Return the final count
return ans;
}
// Driver Code
public static void Main(String[] args)
{
// Given denominations
int N = 123;
int []arr1 = { 1, 5, 10, 20 };
int []arr2 = { 6, 4, 3, 5 };
// Function call
Console.Write(calculateWays(arr1, arr2, N));
}
}
// This code is contributed by 29AjayKumar
Javascript
5
时间复杂度: O(N 3 )
辅助空间: O(1)
有效的方法:让面额的数量用 A、B、C 和 D 表示。解决上述问题的有效方法是计算使用C和D形成的面额的可能数量。然后我们将找到面额为A和B的剩余价值。以下是步骤:
- 初始化数组way[]以存储预先计算的A和B的面额总和。
- 迭代两个嵌套循环以存储由A和B的面额以way[]形成的值的组合。
- 迭代两个嵌套循环以找到由C和D的面额形成的值的所有组合,并将值N – (C*10 + D*20) 的所有可能组合相加,相当于(A * 1) + (乙 * 5) 。
- 上述步骤中所有值的总和就是所需的结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
int ways[1010];
// Function to find the number of
// ways to sum up a total of N
// from limited denominations
int calculateWays(int arr1[], int arr2[],
int N)
{
// Store the count of denominations
int A = arr2[0], B = arr2[1];
int C = arr2[2], D = arr2[3];
// Stores the final result
int ans = 0;
// L1 : Incrementing the values
// with indices with denomination
// (a * 1 + b * 5)
// This will give the number of coins
// for all combinations of coins
// with value 1 and 5
for (int b = 0;
b <= B && b * 5 <= N; b++) {
for (int a = 0;
a <= A
&& a * 1 + b * 5 <= N;
a++) {
ways[a + b * 5]++;
}
}
// L2 will sum the values of those
// indices of ways[] which is equal
// to (N - (c * 10 + d * 20))
for (int c = 0;
c <= C && c * 10 <= (N); c++) {
for (int d = 0;
d <= D
&& c * 10 + d * 20 <= (N);
d++) {
ans += ways[N - c * 10 - d * 20];
}
}
// Return the final count
return ans;
}
// Driver Code
int main()
{
// Given Denominations
int N = 123;
int arr1[] = { 1, 5, 10, 20 };
int arr2[] = { 6, 4, 3, 5 };
// Function Call
cout << calculateWays(arr1, arr2, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static int []ways = new int[1010];
// Function to find the number of
// ways to sum up a total of N
// from limited denominations
static int calculateWays(int arr1[], int arr2[],
int N)
{
// Store the count of denominations
int A = arr2[0], B = arr2[1];
int C = arr2[2], D = arr2[3];
// Stores the final result
int ans = 0;
// L1 : Incrementing the values
// with indices with denomination
// (a * 1 + b * 5)
// This will give the number of coins
// for all combinations of coins
// with value 1 and 5
for(int b = 0;
b <= B && b * 5 <= N; b++)
{
for(int a = 0;
a <= A && a * 1 + b * 5 <= N;
a++)
{
ways[a + b * 5]++;
}
}
// L2 will sum the values of those
// indices of ways[] which is equal
// to (N - (c * 10 + d * 20))
for(int c = 0;
c <= C && c * 10 <= (N); c++)
{
for(int d = 0;
d <= D && c * 10 + d * 20 <= (N);
d++)
{
ans += ways[N - c * 10 - d * 20];
}
}
// Return the final count
return ans;
}
// Driver Code
public static void main(String[] args)
{
// Given denominations
int N = 123;
int arr1[] = { 1, 5, 10, 20 };
int arr2[] = { 6, 4, 3, 5 };
// Function call
System.out.print(calculateWays(arr1, arr2, N));
}
}
// This code is contributed by Princi Singh
蟒蛇3
# Python3 program for
# the above approach
ways = [0 for i in range(1010)];
# Function to find the number of
# ways to sum up a total of N
# from limited denominations
def calculateWays(arr1, arr2, N):
# Store the count of denominations
A = arr2[0]; B = arr2[1];
C = arr2[2]; D = arr2[3];
# Stores the final result
ans = 0;
# L1 : Incrementing the values
# with indices with denomination
# (a * 1 + b * 5)
# This will give the number of coins
# for all combinations of coins
# with value 1 and 5
for b in range(0, B + 1):
if(b * 5 > N):
break;
for a in range(0, A + 1):
if(a + b * 5 > N):
break;
ways[a + b * 5] += 5;
# L2 will sum the values of those
# indices of ways which is equal
# to (N - (c * 10 + d * 20))
for c in range(0, C):
if(c * 10 > N):
break;
for d in range(0, D):
if(c * 10 + d * 20 > N):
break;
ans += ways[N - c * 10 - d * 20];
# Return the final count
return ans;
# Driver Code
if __name__ == '__main__':
# Given denominations
N = 123;
arr1 = [1, 5, 10, 20];
arr2 = [6, 4, 3, 5];
# Function call
print(calculateWays(arr1, arr2, N));
# This code is contributed by gauravrajput1
C#
// C# program for the above approach
using System;
class GFG{
static int []ways = new int[1010];
// Function to find the number of
// ways to sum up a total of N
// from limited denominations
static int calculateWays(int []arr1, int []arr2,
int N)
{
// Store the count of denominations
int A = arr2[0], B = arr2[1];
int C = arr2[2], D = arr2[3];
// Stores the readonly result
int ans = 0;
// L1 : Incrementing the values
// with indices with denomination
// (a * 1 + b * 5)
// This will give the number of coins
// for all combinations of coins
// with value 1 and 5
for(int b = 0;
b <= B && b * 5 <= N; b++)
{
for(int a = 0;
a <= A && a * 1 + b * 5 <= N;
a++)
{
ways[a + b * 5]++;
}
}
// L2 will sum the values of those
// indices of ways[] which is equal
// to (N - (c * 10 + d * 20))
for(int c = 0;
c <= C && c * 10 <= (N); c++)
{
for(int d = 0;
d <= D && c * 10 + d * 20 <= (N);
d++)
{
ans += ways[N - c * 10 - d * 20];
}
}
// Return the final count
return ans;
}
// Driver Code
public static void Main(String[] args)
{
// Given denominations
int N = 123;
int []arr1 = { 1, 5, 10, 20 };
int []arr2 = { 6, 4, 3, 5 };
// Function call
Console.Write(calculateWays(arr1, arr2, N));
}
}
// This code is contributed by 29AjayKumar
Javascript
5
时间复杂度: O(N 2 )
辅助空间: O(1)