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 }

 

 posted on 2014-03-20 04:07  zhuli19901106  阅读(312)  评论(0编辑  收藏  举报