换零钱问题如何限制零钱数
Q05现金支付就是大整数分解问题.将一个大整数,用指定的小整数进行组合。
Q05中作者先通过一个特定的例子,比如求1000元日元的组合,并且给出了限制,最多兑换的硬币个数不超过15.
<!--more-->
1000日元的组合情况:
/* Name: Q05现金支付
Copyright: 52coder.net
Author: 52coder
Date: 04/09/17 23:44
Description: Q05
*/
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,j,k,l;
int cnt = 0;
for (i = 0; i <= 2; i++)
{
for(j = 0;j <= 10;j++)
{
for(k = 0;k <= 20;k++)
{
for(l = 0;l <= 100;l++)
{
if((500*i+100*j+50*k+10*l==1000)&&(i+j+k+l)<=15)
{
cnt += 1;
}
}
}
}
}
printf("%d\n",cnt);
return(0);
}
但这种解法缺少扩展性,比如我想要求解5000元的兑换方式等等,或者更改了币值,假如可以兑换1000一张的硬币等。上面的程序就无法正确求解。
递归思路:
图片来源 知乎用户酿泉 第一个回答作者.
这里以6元拆分成 1元 2元 5元 作为例子,递归的思路是是否使用最大面额零钱与否。
例如最开始6元,我如果使用最大面值为5的零钱,那么还有1元钱需要换成零钱,然后再从 1元 2元 5元中去换钱,此例中由于金额较小,所以只用了一次最大金额,如果面值为100,会用到很多次,使用6元,也能反映问题。
右侧分支是最大面值中不包含5元的情况,那么最大零钱只能使用1元和2元。
依次类推递归,递归的终止条件是分支中出现了0或递归到最小零钱.
/* Name: Q05现金支付
Copyright: 52coder.net
Author: 52coder
Date: 04/09/17 23:44
Description: Q05
*/
#include <stdio.h>
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
#define TOTAL 100
int g_all_coins[] = {50, 25, 10, 5, 1};
#define COIN_NUM ARRAY_SIZE(g_all_coins)
int count(int sz, int coins[], int total)
{
int t_coins[COIN_NUM] = {0};
if(total == 0) return 1;
if(total <= 0) return 0;
if(sz <= 0) return 0;
for(int i = 0; i < sz - 1; i++)
{
t_coins[i] = coins[i+1];
}
return count(sz-1, t_coins, total) + count(sz, coins, total-coins[0]);
}
int main(int argc, char* argv[])
{
printf("count(%d) = %d\n", TOTAL, count(COIN_NUM, g_all_coins, TOTAL));
return 0;
}
现在的问题是该如何限制,最大零钱数呢?比如兑换100的零钱不能兑换100个1元,最多零钱个数不能超过15,这里应该用什么条件去限制呢?
回答:
dp 问题可以写成递归, 也可以写成迭代形式,
- 迭代的话多一个数组保存当前零钱数即可.
- 递归: 要多记录零钱数这个量的话的话, 递归函数中可以加参数, 记录当前所用的总数; 或者用一个全局变量同理1
以上是 换零钱问题如何限制零钱数 的全部内容, 来源链接: utcz.com/p/195010.html