📜  从有限面额中总计N的方法总数

📅  最后修改于: 2021-04-24 16:04:13             🧑  作者: Mango

给定数目N和两个阵列ARR1 []和长度为4的阵列ARR1 []ARR2 []表示的1,5,10,和20以及ARR2 []面额表示1,5,10面额的计,和20 。我们的任务是找到将面额数量有限的N个总数加起来的方法。
例子:

幼稚的方法:让面额的计数由A,B,C和D表示。幼稚的方法是运行嵌套循环。每个循环将参考每个面额的硬币数量。通过以下公式找到使N所需的每种面额的硬币数量:

时间复杂度: O(N 4 )
辅助空间: O(1)
更好的方法:我们可以通过向循环添加一些额外的边界来优化上述幼稚的方法,这将减少一些计算。通过观察,我们可以通过从N中删除面额为1的硬币并丢弃以下循环是否不成立来丢弃一个循环来轻松地降低复杂度:

下面是上述方法的实现:

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


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表示。解决上述问题的有效方法是计算使用CD形成的面额的可能数目。然后,我们将找到面额为AB的剩余价值。步骤如下:

  1. 初始化array Ways []以存储AB的面额的预先计算的总和。
  2. 迭代两个嵌套循环来存储的值由A的面额和B方式形成的组合[]。
  3. 迭代两个嵌套循环,以找到由CD表示的值的所有组合,然后将值N –(C * 10 + D * 20)的所有可能组合相加,这等效于(A * 1)+( B * 5)
  4. 上一步中所有值的总和是必需的结果。

下面是上述方法的实现:

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)