两套代码solution1,solution2; 复杂度分析: 可以用DP做,这里我提供两个代码。都是基于DP,他们在m等于10000以下,一秒内都可以运行完。solution1在M比较小的时候比solution2快(m不超过十万),复杂度都是m平方。在m比较小的时候(十万以下),solution1明显比2快。(solution1前面的常数小)。 代码解释: solution1 代码中dp 是一个二维数组:dp[index][sum],index表示第index种货币,sum表示当前需要组合成的数. dp[index][sum] 表示用第大于等于下标为index的硬币组成SUM这个数有多少种方式。 那么可以导出这样一个公式: 式中index 代表硬币的下标。(我的代码里下标为0的硬币是100,下标为1的是50.。。。),value是当前下标硬币的值,num是当前硬币的数量。 我们所要求的的是用下标大于等于0的硬币(就是所有硬币)组成数M的方式有多少种。 solution2: dp 数组仍然是二维数组,dp[index][sum]  中的index,sum意义不变,但是dp[index][sum]本身的意义有很小的变化:dp[index][sum] 代表它被访问的次数。.举个例子:m=101;一种可能的组合 1*100+0*50+0*20+。。。+1*1;还有一种组合 0*100+2*50+。。。+1*1;可以看到,第一种组合为1,0,0,0,0,0,1,第二种为0,2,0,0,0,0,1,他们在在访问第三种硬币的时候,都是要求第二种以后的硬币组合出一个1(因为前两种(下标0,1)已经组合出了100),所以需要后面下标为2,3,4,5,6种硬币组合出1;也就是说dp[2][1]被访问了两次。这样也就是说,我们只需要统计最后一种硬币在所有可能的和上被访问的次数,也就是我们的总次数。   递推公式为: value是index硬币的值,num是数量。 如果不用递归函数,空间复杂度还其实可以优化,因为每个状态只跟上一个状态有关。 具体代码注释下一条。
点赞 评论

相关推荐

昨天 20:41
已编辑
北京交通大学 算法工程师
字节跳动 训练框架研发 (N+2) * (12 + 3) 硕士211
点赞 评论 收藏
分享
dian3b:挺妙的,如果上纲上线显得不合人心,但是这样以来既能监督适当摸鱼,也有一定的人文关怀。
摸鱼被leader发现了...
点赞 评论 收藏
分享
12-24 14:26
东北大学 Java
一只乌鸦:重邮+东北,好经典的学校
最后再改一次简历
点赞 评论 收藏
分享
牛客网
牛客网在线编程
牛客网题解
牛客企业服务