给定数目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
5
时间复杂度: O(N 3 )
辅助空间: O(1)
高效方法:让面额的计数用A,B,C和D表示。解决上述问题的有效方法是计算使用C和D形成的面额的可能数目。然后,我们将找到面额为A和B的剩余价值。步骤如下:
- 初始化array Ways []以存储A和B的面额的预先计算的总和。
- 迭代两个嵌套循环来存储的值由A的面额和B的方式形成的组合[]。
- 迭代两个嵌套循环,以找到由C和D表示的值的所有组合,然后将值N –(C * 10 + D * 20)的所有可能组合相加,这等效于(A * 1)+( B * 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
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
5
时间复杂度: O(N 2 )
辅助空间: O(1)