钱币兑换

Problem 45: 钱币兑换问题


Time Limit:1 Ms| Memory Limit:128 MB
Difficulty:2

Description

在一个国家仅有1分,2分,3分硬币,将钱N分兑换成硬币有很多种兑法。请你编程序计算出共有多少种兑法。

Input

每行只有一个正整数N,N小于32768。(有多组测试数据,以EOF结束)

Output

对应每个输入,输出兑换方法数。

Sample Input

20
2934

Sample Output

44
718831




递归做的超时:


#include<stdio.h>


int f(int n, int m);


int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
printf("%d\n",f(n,3));
}
return 0;
}


int f(int n, int m)
{
if(n == m && m != 1)
return 1 + f(n, m-1);
else if(n > m && m != 1)
{
  return
f(n - m,m) + f(n,m - 1);


}
else if(n < m && m != 1)
{
return f(n, n) ;


}
else if(m == 1)
return 1;
}



2.把递归换成递推:

#include<stdio.h>
#define MAX 32768
int main()
{
int n;
int f[MAX][4];//f[n][m]n表示钱币值,m表示兑换的钱币的小于m;如f[5][3]表示把5换成不大与3的面值;
int i, j;
while(scanf("%d", &n) != EOF)
{
for(i = 1; i <= n; i++)
for(j = 1; j <= 3; j++)
{
if(i == j && j != 1)
f[i][j] = 1 + f[i][j - 1];
else if(i < j && j != 1)//i < j 说明不能把i 的面置换为包含j 分的;所以让j == i;
{
f[i][j] = f[i][i];
}
else if(i > j && j != 1)//i > j 则可继续将i分下去;
f[i][j] = f[i - j][j] + f[i][j - 1];
else
if(j == 1)//分到含有1时说明把i 分成了i 个1 的面值;
f[i][1] = 1;
}
printf("%d\n", f[n][3]);
}
}


思想是把大问题化成小问题,如求9换成3,2,1的f[9][3]分成f[9-3][3](含有3的面值)和f[9][3-1](不含3的面值);
再把f[6][3]分成f[3][3]和f[6][2];一直分到f[][1] = 1;
把f[9][2]也按如此分;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值