题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2069
题目大意:
给一个数字,用1, 5, 10, 25, 50 这五种硬币,最多用100枚,有多少种组合方式。
题目思路:
这道题和之前的题目不同,有了硬币个数的限制,所以需要加上一维表示硬币的个数就可以了。d[i][j]表示价值为 i 的最多用 j 枚硬币有多少中组合方式。很多人用母函数做,感觉DP做简单多了……
参考博客:http://www.cnblogs.com/qiufeihai/archive/2012/09/11/2680840.html
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 const int MAX = 250+10; 7 int d[MAX][MAX], n, a[5] = {1, 5, 10, 25, 50}; 8 void solve() { 9 while (~scanf("%d", &n)) { 10 int i, j, k; 11 memset(d, 0, sizeof(d)); 12 d[0][0] = 1; 13 for (k = 0; k < 5; ++k) { 14 for (j = 1; j <= 100; ++j) { 15 for (i = a[k]; i <= n; ++i) { 16 d[i][j] += d[i-a[k]][j-1]; 17 } 18 } 19 } 20 int sum(0); 21 for (i = 0; i <= n; ++i) { 22 sum += d[n][i]; 23 } 24 printf("%d\n", sum); 25 } 26 } 27 int main(void) { 28 solve(); 29 return 0; 30 }
还有要注意一点,初始化要d[0][0] = 1 因为题目中说:Note that we count that there is one way of making change for zero cent.
只能初始化这个值,不要把所有的d[0][i]都初始化为1了……因为这显然就把结果增加了。。这是因为从 d[0][0] 可以推算出后面的d[0][1,,,,100]