数组的最小子集,其总和等于key。条件:值可以使用任意次数

时间:2014-04-04 11:42:18

标签: arrays algorithm

我在采访中被问到这个问题。 给出一个“N' N'硬币,它们的值在一个数组A []中,返回所需的最小硬币数量,以及“S' (你可以使用你想要的硬币)。如果无法汇总到' S',则返回-1 请注意,我可以多次使用相同的硬币。

示例:

输入#00:

硬币面额:{1,3,5}

所需金额(S):11

输出#00:

3

说明: 所需的最小硬币数量为:3 - 5 + 5 + 1 = 11;

Sorting the array and start it by both ends之外,还有其他更好的方式吗?

2 个答案:

答案 0 :(得分:0)

这是change-making problem

您似乎正在考虑一种简单的贪婪方法,并不总能产生最佳结果。如果你从两端开始详细说明你究竟是什么意思,我可能会想出一个反例。

采用dynamic programming方法取自here

  

C[m]d1金额更改所需的最低面额硬币d2dk,...,m。在为m金额进行更改的最佳解决方案中,必须存在一些第一枚硬币di,其中di < m。此外,解决方案中剩余的硬币本身必须是对m - di进行更改的最佳解决方案。

     

因此,如果di是进行m金额更改的最佳解决方案中的第一个硬币,那么C[m] = 1 + C[m - di],即一个di硬币加C[m - di] }硬币以最佳方式更改m - di金额。我们不知道哪枚硬币di是第一枚硬币;但是,我们可以检查所有n这样的可能性(受di < m的约束),并且根据定义,最优解的值必须对应于1 + C[m - di]的最小值。 / p>      

此外,当对0进行更改时,最佳解决方案的值显然是0个硬币。因此,我们有以下重复。

C[p] = 0                                if p = 0
       min(i: di < p) {1 + C[p - di]}   if p > 0

答案 1 :(得分:0)

寻路算法(Dijkstra,A *,中间会议等)可能适用于这样的图:

                  0
                1/|\5
                / |3\
               /  |  \
             1    3    5
           1/|\51/|  ...
           / |3\/ |3
          /  | /\ |
         2   4    6
          ....

其他方式是递归二分法。比方说,如果我们不能用一枚硬币获得总和S,我们就会开始尝试递增金额(S / 2,S / 2)......(S-1,1),直到我们找到合适的硬币或达到S = 1