aho*_*ota 11 c++ algorithm combinations combinatorics
我最近面临一个编程算法的提示,我不知道该怎么做.我以前从来没有真正写过算法,所以我对此有点新意.
问题是写一个程序,以确定收银员根据硬币值和硬币数量作为变化回馈所有可能的硬币组合.例如,可能有一个有4个硬币的货币:2美分,6美分,10美分和15美分硬币.这有多少组合等于50美分?
我正在使用的语言是C++,虽然这并不重要.
编辑:这是一个更具体的编程问题,但我如何分析C++中的字符串来获取硬币值?它们是在文本文档中给出的
4 2 6 10 15 50
Run Code Online (Sandbox Code Playgroud)
(在这种情况下,数字对应于我给出的例子)
这是Java中的递归解决方案:
// Usage: int[] denoms = new int[] { 1, 2, 5, 10, 20, 50, 100, 200 };
// System.out.println(ways(denoms, denoms.length, 200));
public static int ways(int denoms[], int index, int capacity) {
if (capacity == 0) return 1;
if (capacity < 0 || index <= 0 ) return 0;
int withoutItem = ways(denoms, index - 1, capacity);
int withItem = ways(denoms, index, capacity - denoms[index - 1]);
return withoutItem + withItem;
}
Run Code Online (Sandbox Code Playgroud)
这似乎有点像分区,除了你不在1:50使用所有整数.它似乎也与bin打包问题类似,略有不同:
实际上,在考虑它之后,它是一个ILP,因此NP难.
我建议一些动态编程appyroach.基本上,您可以定义一个值"余数"并将其设置为您的目标(例如,50).然后,在每一步,您都会执行以下操作:
因此,如果余数为50且最大的硬币值为25和10,那么您将分为两种情况:
1. Remainder = 25, Coinset = 1x25
2. Remainder = 50, Coinset = 0x25
Run Code Online (Sandbox Code Playgroud)
下一步(对于每个分支)可能如下所示:
1-1. Remainder = 0, Coinset = 2x25 <-- Note: Remainder=0 => Logged
1-2. Remainder = 25, Coinset = 1x25
2-1. Remainder = 40, Coinset = 0x25, 1x10
2-2. Remainder = 50, Coinset = 0x25, 0x10
Run Code Online (Sandbox Code Playgroud)
每个分支将分成两个分支,除非: