《Cracking the Coding Interview》——第9章:递归和动态规划——题目8

2014-03-20 04:04

题目:给你不限量的1分钱、5分钱、10分钱、25分钱硬币,凑成n分钱总共有多少种方法?

解法:理论上来说应该是有排列组合的公式解的,但推导起来太麻烦而且换个数据就又得重推了,所以我还是用动态规划解决。

代码:

 1 // 9.8 Given unlimited quarters(25 cents), dimes(10 cents), nickels(5 cents) and pennies(1 cent), how many ways are there to represent n cents.

 2 #include <cstdio>

 3 #include <vector>

 4 using namespace std;

 5 

 6 // f(n, 1) = 1;

 7 // f(n, 1, 5) = sigma(i in [0, n / 5]){f(n - i * 5, 1)};

 8 // f(n, 1, 5, 10) = sigma(i in [0, n / 10]){f(n - i * 10, 1, 5)}

 9 // f(n, 1, 5, 10, 25) = sigma(i in [0, n / 25]){f(n - i * 25, 1, 5, 10)}

10 int main()

11 {

12     int n;

13     vector<vector<long long int> > v;

14     const int MAXN = 1000000;

15     const int c[4] = {1, 5, 10, 25};

16     

17     int i, j;

18     v.resize(2);

19     for (i = 0; i < 2; ++i) {

20         v[i].resize(MAXN);

21     }

22     int flag = 1;

23     int nflag = !flag;

24     for (i = 0; i < MAXN; ++i) {

25         v[0][i] = 1;

26     }

27     

28     for (i = 1; i < 4; ++i) {

29         for (j = 0; j < c[i]; ++j) {

30             v[flag][j] = v[nflag][j];

31         }

32         for (j = c[i]; j < MAXN; ++j) {

33             v[flag][j] = v[nflag][j] + v[flag][j - c[i]];

34         }

35         flag = !flag;

36         nflag = !nflag;

37     }

38     flag = !flag;

39     nflag = !nflag;

40     

41     while (scanf("%d", &n) == 1 && n >= 0 && n < MAXN) {

42         printf("%lld\n", v[flag][n]);

43     }

44     for (i = 0; i < 2; ++i) {

45         v[i].clear();

46     }

47     v.clear();

48     

49     return 0;

50 }

 

你可能感兴趣的:(interview)