C++ 找零问题程序

C++ 找零问题程序

在本文中,我们将看到最常见的面试问题。找零问题是动态规划方法的一个很好的示例。现在让我们理解问题陈述。

问题陈述

给定N和一个包含一些数字(代表硬币面值)的数组(coins[])。N是需要找零的金额,数组包含各种面值的硬币。任务是使用数组中的硬币进行找零。找零的方式是使用尽量少的硬币。

示例

让我们以一个输入数组coins[] = {10, 25, 5},硬币总数为3为例。

我们有N = 30。

输出结果是 two ,因为我们可以使用一个25卢比的硬币和一个5卢比的硬币组成30(25 + 5 = 30)。

同样,coins[] = {1, 9, 6, 5},硬币总数为4。

N = 13。

输出结果是 three ,因为我们需要两个6卢比的硬币和一个1卢比的硬币(6 + 6 + 1 = 13)。

方法1

该方法使用递归方法。我们从N开始,每次迭代时,将问题分解为较小的子问题。这是通过从硬币数组中取出每个硬币并从N中减去来完成的。当N等于零时,我们得到了所需的解决方案。为了得到最优的答案,我们返回所有组合中的最小值。

C++代码

#include 
using namespace std;


int minCoins(int coins[], int total_coins, int N) // Function to return the minimum // coins needed 
{
        if (N == 0) // If we have a combination then 
        return 0;

    int result = INT_MAX; // Currently result is initialised as INT_MAX 

    for (int i = 0; i < total_coins; i++) // run until availability of coins
    {
        if (coins[i] <= N) { // Add to the list of counting 
            int sub_res = 1 + minCoins(coins, total_coins, N - coins[i]); // add 1 due to the coin inclusion
            // see if result can minimize
            if (sub_res < result)
                result = sub_res;
        }
    }
    return result;
}

int main()
{
    int coins[] = { 10, 25, 5 };
    int sum = 30; // the money to convert
    int total_coins = 3; // total availability of coins
    cout << "Minmum coins needed are " << minCoins(coins, total_coins, sum);
}

输出

Minimum coins needed are 2

上述解决方案对于更大的输入不起作用。在这种情况下,递归的方法会失败。

现在让我们来看一种优化的方法。

方法2

这种方法使用自底向上的动态规划思想。

由于子问题反复计算,存在重叠子问题的条件。可以使用记忆化的属性解决重复计算的问题,即创建一个dp[]数组,用于存储特定阶段的计算值。在每个阶段计算所有可能的组合。在所有组合之后,dp[]数组的最后一个值给出了答案。

C++代码

#include <bits/stdc++.h>
using namespace std;

int coins[] = { 10, 25, 5 }; // coins array
int dp[1000] = { 0 }; // array for memoisation
int minCoins(int N, int M) // N is the sum , M is total_coins
{

    for (int i = 0; i <= N; i++)
        dp[i] = INT_MAX; // Initialise all dp[] value to INT_MAX

    dp[0] = 0; // Base case if sum becomes zero min rupees = 0

    //Iterating in the outer loop for possible values of sum between 1 to N
    //Since our final solution for sum = N might depend upon any of these values
    for (int i = 1; i <= N; i++) {
        //Inner loop denotes the index of coin array.
        //For each value of sum, to obtain the optimal solution.
        for (int j = 0; j < M; j++) {
            //i ?> sum
            //j ?> next coin index
            //If we can include this coin in our solution
            if (coins[j] <= i) {
                //Solution might include the newly included coin
                dp[i] = min(dp[i], 1 + dp[i - coins[j]]);
            }
        }
    }
    return dp[N];
}

int main()
{

    int sum = 30; // the money to convert
    int total_coins = 3; // total availability of coins
    cout << "Minimum coins needed are " << minCoins(sum, total_coins);
}

输出

Minimum coins needed are 2

代码的时间复杂度为O(total_coins + sum)。这是一种经过优化的方法,因为在每个阶段存储结果并在其他迭代中利用它。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程