硬币组合问题

作者: 大爽兔 | 来源:发表于2016-04-08 19:31 被阅读485次

问题描述

有 N 枚硬币,面值分别是 a1,a2,..ai,..aN,问可不可以凑成 M?

思路分析

这个题,直接想到的就是遍历,复杂度会非常大,否掉。直观方法如此复杂的问题,通常可以分解成子问题来解决:
考虑 ai,看 a1…ai 这个子序列是否可以组成 M。我们把原问题分解成了子问题,并假设该子问题的子问题,即 a1…ai-1 不能组成 M。为什么这么假设呢?问题分解的求解思路是找一个分解路径,然后实际求的时候从最小的子问题开始算,也就是 a1,然后逐步增大问题规模: a1,a2; a1,a2,a3;… 当到达某个规模的子问题时如果符合条件就终止,不再计算后面更大的子问题。因此既然算到 a1…ai 这个子问题,那么它的更小的子问题当然是没有符合条件。
在解决 a1…ai 这个问题时,需要依赖它的子问题 a1…ai-1 求出的结果。现在问题的关键就是子问题保存了什么。原问题是问是否可以凑成M,那么子问题只保存一个 bool 值是否可以?不可,它没有提供可用的信息。
再想一下,既然原问题的意思是求数组中的数是否可以组合成一个给定的值,那么将原问题的表述稍微改变一下:该数组可以凑成哪些数,有没有一个是M?
现在就知道了,子问题 a1..ai-1 要记录的就是它当前可以组成哪些数。同样,a1..ai 也得求这个信息,而且根据前一子问题来求。到了这步,递推的关系就容易想清楚了:
a1..ai-1 可以组成的数的集合是:Ai-1
a1..ai 可以组成的数的集合由两部分构成:

  • Ai-1
  • Ai-1 的每个数加上 ai

两个集合可能有相同元素,需要 union 合并一下,就能得到 Ai。
递推关系找到了,需要从最小的子问题开始求。现在需要验证最小的子问题是否可以求A1?显然可以。那么问题就可以这么解决了。

代码

include <set>#include <iostream>using namespace std;bool CombinationProblem(const int* arr, int len, int M ){ if(arr == NULL) return false; set<int> s1, s2; s1.insert(0); // s1 保存前一子问题的组合 s2.clear(); // s2 保存s1加上当前元素后的组合 for (int i=0; i<len; ++i) { for (auto j=s1.begin(); j!=s1.end();++j) { s2.insert(*j + arr[i]); } s1.insert(s2.begin(), s2.end()); s2.clear(); if (s1.end() != s1.find(M)) { return true; } } return false;}void main(){ int testArr[10] = {1, 5, 3, 9, 55, 34, 2, 8, 22, 4}; int M = 99; cout<<CombinationProblem(testArr, 10, M)<<endl;}

相关文章

  • 硬币组合问题

    问题描述 有 N 枚硬币,面值分别是 a1,a2,..ai,..aN,问可不可以凑成 M? 思路分析 这个题,直接...

  • 07-05:动态规划review2

    动态规划常见问题 零、组合问题 1、硬币问题 n=len(arr) if n<=0 or aim<=0: ...

  • 动态规划 凑硬币问题

    凑硬币问题 假设有 1 元,3 元,5 元的硬币若干(无限),现在需要凑出 11 元,问如何组合才能使硬币的数量最...

  • 贪心算法(硬币找零问题)

    问题描述 小Q手上有 n 种不同面值的硬币,每种硬币有无限多个。为了方便购物,他希望带尽量 少的硬币,但是要能组合...

  • 零钱兑换 II

    问题描述 给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。...

  • 硬币问题-动态规划

    问题描述 假设有 1 元,3 元,5 元的硬币若干(无限),现在需要凑出 11 元,问如何组合才能使硬币的数量最少...

  • 刷题笔记(经典题目汇总)

    1.硬币找零问题(腾讯q币找零) 解法:贪心策略 只考虑最少需要的硬币总数而不考虑具体的组合对于 1,2,5,10...

  • 硬币问题

  • Hackerrank The Coin Change Probl

    这是一道比较简单的一维dp问题。给一个数字n,然后再给m种不同面值的硬币,求这个数字能被这些硬币以多少种组合方式组...

  • 数据结构与算法之硬币组合问题

    题目描述:现有硬币六种,分别为1元、5元、10元、20元、50元、100元,假设每种硬币数量均无限多,问用它们来凑...

网友评论

    本文标题:硬币组合问题

    本文链接:https://www.haomeiwen.com/subject/ecivlttx.html