Problem 45: 钱币兑换问题
Time Limit:1 Ms| Memory Limit:128 MB
Difficulty:2
Description
Input
Output
Sample Input
2934
Sample Output
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]也按如此分;