【发布时间】:2014-08-27 18:23:08
【问题描述】:
我正在复习算法课的讲义,我开始思考这个问题:
给定不同类型的具有不同价值的硬币,找出所有硬币配置以加起来不重复。
在课堂上,我们解决了这个问题,找出所有可能的求和方式的数量以及求和的最少硬币数量。但是,我们从未尝试真正找到解决方案。
我正在考虑用动态规划解决这个问题。
我提供了递归版本(为简单起见,我只打印解决方案):
void solve(vector<string>& result, string& currSoln, int index, int target, vector<int>& coins)
{
if(target < 0)
{
return;
}
if(target == 0)
{
result.push_back(currSoln);
}
for(int i = index; i < coins.size(); ++i)
{
stringstream ss;
ss << coins[i];
string newCurrSoln = currSoln + ss.str() + " ";
solve(result, newCurrSoln, i, target - coins[i], coins);
}
}
但是,我在尝试使用 DP 解决问题时遇到了困难。 我有两个主要障碍:
- 我不知道应该使用什么数据结构来存储以前的答案
- 我不知道我的自下而上过程(使用循环替换递归)应该是什么样子。
欢迎任何帮助,我们将不胜感激!
感谢您的宝贵时间。
【问题讨论】:
-
如果你可以使用动态编程来解决这个问题,这对我来说并不是很明显。如果我找到 50 美分,添加四分之一,然后在 25 美分上“递归”,找到 1 四分之一和 5 镍币。然后我回到开始,尝试 5 个 nickles,检查 25cents 的结果,找到计算的 2 个解,所以我说总共有 4 个解。但是 1 个四分之一 + 5 个镍和 5 个镍 + 1 个四分之一是重复的。
-
可能有很多可能的变革解决方案,因此 DP 会有所帮助,但可能仍需要非常非常长的时间才能完成。你同意吗?
-
我写了一个幼稚的版本来比较:coliru.stacked-crooked.com/a/d2c06ff6aa2ea45a
-
你有没有在谷歌上寻找过“改变”?
-
是的。我做到了。其中大多数只是“最小数量的硬币”和“总方式”。很少有人真正费心去寻找所有的解决方案,但他们都没有使用 DP。我欢迎建设性的 cmets,但只是问我是否在谷歌上搜索没有帮助......如果你能给我一个链接到你找到解决方案的地方,我将不胜感激。@tmyklebu
标签: c++ algorithm recursion dynamic-programming